home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-08 | 93.4 KB | 2,876 lines |
- /* Amiga Type Engine 1.5 (BETA 5)
-
- Perpetrated by OPTIMUS PRIME, AUTOBOT Commander
- (Also known as Gordon Fecyk)
-
- Source is specific for DICE C 3.0 for the Amiga. Requires
- postlib.h and post.library 1.7 by Adrian Ayward. Also works
- with HWGPOST.
-
- Additions since 1.0:
- better CharKern handling so weird italic characters don't suffer from tail chop
- use of .AFM files and ATEencoding.ps instead of typeface itself to improve
- rendering speed and character spacing
-
- Additions since 1.2:
- better soft style handling. I change fonts in the Text() patch now, to
- accomodate stupid programs that don't even try to load styles other than
- the plain style, then SetSoftStyle() them
- AvailFonts() patch to avoid requiring stupid .font files, and an attempt
- to reduce disk access by intercepting AvailFonts() calls with a zero buffer
-
- Additions for 1.3c
- More efficient searches through the fontlist; since the patches do searches,
- why does the mainline need to?
-
- Additions for 1.3d
- Crude CLI detachment via Execute(argv[0], 0, 0) which actually works.
- Minor char chop fixing, but it chops on the other side now. Arrgh.
- Beginning of parameter passing via public message port, facility
- to add more parameters as needed.
- No more breaking via CTRL-C: must type ATE -exit to break.
- Now can run from Workbench!!!!
-
- Additions for 1.4
- Removed all references to callextfunc, so I no longer need several
- functions that the PostScript code uses.
- Began introducing more parameters into parameter handler, introduced
- -trace and -debug.
- Introduced function to rebuild ATE font lists upon adding or removing
- typefaces, and for changing the AvailFonts size options.
- Improved character rendering which takes about 2/3 the original time
- to draw! FAAAAST!
- Expunge patch for post.library added. In a low memory panic, ATE will
- free up unused TextFonts and FontNodes.
-
- New for 1.5:
- Modifications for HWG version of post (V22). This requires post V22
- to operate along with the various extensions for this library.
- Support for ta_DeviceDPI following Commodore's misguided spec
- Support for NewScaledDiskFont() following a slightly better spec
-
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdarg.h>
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <exec/libraries.h>
- #include <clib/exec_protos.h>
- #include <dos/dos.h>
- #include <graphics/rastport.h>
- #include <graphics/text.h>
- #include <diskfont/diskfont.h>
- #include <clib/utility_protos.h>
- #include <utility/tagitem.h>
- #include "hwgpostlib.h"
-
- /* Set to TRUE for printing PostScript debugging messages */
- BOOL optTrace;
- BOOL optDebug;
- /* Another BOOL for allowing software styles on ATE fonts */
- BOOL optSoftStyles;
- /* Default density of untagged fonts */
- int defaultDPI;
-
- /* PostScript external data */
- struct Library *PSbase; /* Library struct for post.library */
- struct PSparm *psParm; /* For some stupid reason this needs */
- /* to be external. Thanks Adrian. */
- int psActivation; /* Record for PS activation */
- int psError; /* Error checking for each PS call */
- char nameBuffer[100 + 5]; /* Bogus space for PS initalization */
-
- /* end of PostScript external data (I hope) */
-
- /* External pointers for system patches */
- struct Library *diskfontBase;
- struct Library *gfxBase;
-
- /* This is an extended diskfont header with two longwords preceeding it.
- This is for the NewScaledDiskFont patch but it will apply to all
- ATE fonts, just to streamline some of the code. Normal FontNodes
- won't use this extra data. */
- struct ExtDFHeader {
- ULONG edf_Length;
- ULONG edf_NextSeg; /* This will be zero */
- struct DiskFontHeader edf_DFHeader; /* Including TextFont */
- };
-
- /* FontNode struct, holds all data specific to a built TextFont */
- struct FontNode {
- /* basic Node struct for searches */
- struct Node fn_Node;
- /* format for fn_Name: "%50s / %5d / %2x" for "name / size / style" */
- /* fn_Name is mainly used for node searching */
- char fn_Name[64];
- /* As of Beta 3B, this is in to prevent re-opening of error-prone fonts */
- BOOL fn_BlackList;
- /* Set to non-zero if a certain character exists already */
- char fn_BuiltChars[256];
- /* Data POST uses */
- int fn_LowChar, fn_HighChar;
- int fn_OptBaseLine, fn_BaseLine;
- int fn_NominalWidth, fn_NominalCount;
- char fn_OptFontEncoding, fn_TypefaceName[64];
- int fn_MaxFontLength, fn_MaxCharLength;
- int fn_MaxModulo, fn_MaxWidth, fn_ActWidth;
- int fn_NomCount, fn_NomWidth;
- int fn_BaseLength, fn_FontSize;
- UBYTE fn_Style;
- /* Bounding box & graphic position info */
- int fn_CharWidths[256];
- int fn_LowLeftX[256], fn_LowLeftY[256];
- int fn_UpRightX[256], fn_UpRightY[256];
- int fn_CharPosX, fn_CharPosY;
- /* XDPI generated from (ta_XDPI / ta_YDPI) * defaultDPI
- as per Commodore spec */
- int fn_XDPI;
- /* Pointers to data areas in the TextFont struct */
- char *fn_CharData, *fn_CharFontName;
- short *fn_CharLoc, *fn_CharSpace, *fn_CharKern;
- /* Heinz says I can use multiple page descriptions now. Not. */
- // struct PSdevice fn_Page;
- /* Ptr to a diskfont header with an 8 byte prefix (Seglist header) */
- struct ExtDFHeader *fn_ExtDFHeader;
- /* The TextFont in question */
- struct TextFont *fn_TextFont; /* Within fn_extDFHeader */
- /* the TextFont will soon immediately follow the FontNode struct */
- };
-
- /* modes for fn_BuiltChars */
- #define CHAR_NOT_DRAWN 0
- #define CHAR_DRAWN 2
- #define CHAR_NEEDED 1
-
- /* ATEFontList struct, contains a Semaphore and the FontList itself */
- struct ATEFontList {
- struct SignalSemaphore ateSemaphore;
- struct List fontList;
- };
-
- /* One external pointer so the patches can search the list */
- struct ATEFontList *ateFontList;
-
- /* Simple fcn that generates an OpenCount of all ATE fonts in use */
- int CountOpenFonts(void);
-
- /* Logic behind ATEAvailFonts struct:
- Stores enough data to build AvailFonts structs for the AvailFonts()
- patch. PrepAvailFonts() builds this structure from the size max and
- size increment values, and the _ATE_ names fount in FONTS:.
- Because changes can happen anytime, I set aside an external Semaphore
- to protect the ptr to this data, as even the ptr can change at any time.
- TextAttrs use pointers to names, not the names themselves. So the names
- need to be in that memory space somewhere. I work around diskfont.library's
- AvailFonts() call by spotting the temporary AvailFontsHeader in the middle
- of the memory pool, then call it with the original parameters, and copy
- the NumEntries value. Then I add my extra data at the end of where
- diskfont.library put its extra data, and fill in the beginning of the pool
- with my (T)AvailFonts, NumEntries plus numTAs, then exit. (whew.)
-
- ***** This is the buggiest part, even though I tested it many times,
- some apps just don't like it. I think the apps are broken. */
-
- /* ATEAvailFonts struct, contains needed info for AvailFonts() patch */
- struct ATEAvailFonts {
- int aaf_SizeDiskFonts; /* Memory for diskfonts before ATE */
- int aaf_SizeATEFonts; /* Memory for all ATE TTextAttrs */
- int aaf_SizeATEData; /* Size of fontname & tag data */
- struct TagItem aaf_ATETags[2]; /* Taglist for ATE TTextAttrs */
- char *aaf_FontNames; /* ptr to start of ATE fontnames */
- int aaf_NumNames; /* total all unique ATE fontnames */
- int aaf_SizeInc; /* Point size increment */
- int aaf_SizeMax; /* Maximum point size */
- /* char aaf_FontNames[][32]; Start of font names */
- /* memory sizes based on TAvailFonts structures, just to be safe */
- };
-
- /* One external pointer for ATEAvailFonts for other processes to see */
- struct ATEAvailFonts *ateAvailFonts;
- /* Semaphore to allow safe access */
- struct SignalSemaphore aafSemaphore;
- /* Here's the fcn that builds this struct.
- diskfont size of zero means hide all Amiga diskfonts */
- struct ATEAvailFonts *PrepATEAvailFonts(int sizeMax, int sizeInc, int diskfontSize);
-
- /* An external for the encoding array */
- char encodingExternal[256][24];
-
- /* Message structures, all based on my extended Message struct ATEMessage */
- struct ATEMessage {
- struct Message ate_Message;
- int ate_MsgLength;
- struct MsgPort *ate_DestPort;
- };
-
- struct DiskfontMsg {
- struct ATEMessage df_ATEMsg;
- struct TextAttr *df_TextAttr;
- struct FontNode *df_FontNode;
- struct TextFont *df_TextFont;
- BOOL df_ATEFont;
- };
-
- struct NsdfMsg {
- struct ATEMessage nsdf_ATEMsg;
- struct TextFont *nsdf_TextFont;
- struct TextAttr *nsdf_TextAttr;
- struct DiskFontHeader *nsdf_DFHeader;
- };
-
- struct TextMsg {
- struct ATEMessage tm_ATEMsg;
- struct RastPort *tm_RastPort;
- struct FontNode *tm_FontNode;
- STRPTR tm_Chars;
- WORD tm_Length;
- BOOL tm_ATEFont;
- };
-
- struct SSStyleMsg {
- struct ATEMessage ss_ATEMsg;
- struct RastPort *ss_RastPort;
- ULONG ss_NewStyle;
- ULONG ss_Enable;
- struct TextFont *ss_ChangedFont;
- struct FontNode *ss_FontNode;
- ULONG ss_SoftStyleNeeded;
- BOOL ss_ATEFont;
- };
-
- struct CommandMsg {
- struct ATEMessage cm_ATEMsg;
- int cm_ArgC;
- char **cm_ArgV;
- BOOL cm_Result;
- };
-
- /* Ptrs to MsgPorts internal to ATE */
- struct MsgPort *ateODFPort, *ateTextPort, *ateSSSPort, *ateNSDFPort;
-
- /* Signal info for the Expunge() patch, for this task
- and the allocated signal */
- struct Task *ateMainTask;
- BYTE ateDfeSigBit;
-
- /* Prototypes of system patches and original functions */
- __geta4 __regargs struct TextFont *NewOpenDiskFont(__A0 struct TextAttr *textAttr, __A6 struct Library *libBase);
- __geta4 struct TextFont *(*OldOpenDiskFont)(__A0 struct TextAttr *textAttr, __A6 struct Library *libBase);
- __geta4 __regargs void NewText(__A1 struct RastPort *rastPort, __A0 STRPTR textString, __D0 WORD length, __A6 struct Library *libBase);
- __geta4 void (*OldText)(__A1 struct RastPort *rastPort, __A0 STRPTR textString, __D0 WORD length, __A6 struct Library *libBase);
- __geta4 __regargs ULONG NewSSStyle(__A1 struct RastPort *rastPort, __D0 ULONG newStyle, __D1 ULONG enable, __A6 struct Library *libBase);
- __geta4 ULONG (*OldSSStyle)(__A1 struct RastPort *rastPort, __D0 ULONG newStyle, __D1 ULONG enable, __A6 struct Library *libBase);
- __geta4 __regargs LONG NewAvailFonts(__A0 struct AvailFontsHeader *afhBuffer, __D0 LONG afBufSize, __D1 ULONG afFlags, __A6 struct Library *libBase);
- __geta4 LONG (*OldAvailFonts)(__A0 struct AvailFontsHeader *afhBuffer, __D0 LONG afBufSize, __D1 ULONG afFlags, __A6 struct Library *libBase);
- __geta4 __regargs ULONG NewDFbaseExpunge(__A6 struct Library *libBase);
- __geta4 ULONG (*OldDFbaseExpunge)(__A6 struct Library *libBase);
- __geta4 __regargs struct DiskFontHeader *NewNSDF(__A0 struct TextFont *tf, __A1 struct TextAttr *ta, __A6 struct Library *libBase);
- __geta4 struct DiskFontHeader *(*OldNSDF)(__A0 struct TextFont *tf, __A1 struct TextAttr *ta, __A6 struct Library *libBase);
-
- /* These were a misguided attempt to work around a bug in Deluxe Video III */
- //__geta4 __regargs WORD NewTextLength(__A1 struct RastPort *rastPort, __A0 STRPTR aString, __D0 WORD strCount, __A6 struct Library *libBase);
- //__geta4 WORD (*OldTextLength)(__A1 struct RastPort *rastPort, __A0 STRPTR aString, __D0 WORD strCount, __A6 struct Library *libBase);
- //__geta4 __regargs struct TextExtent *NewTextExtent(__A1 struct RastPort *rastPort, __A0 STRPTR aString, __D0 WORD strCount, __A2 struct TextExtent *te);
- //__geta4 struct TextExtent *(*OldTextExtent)(__A1 struct RastPort *rastPort, __A0 STRPTR aString, __D0 WORD strCount, __A2 struct TextExtent *te, __A6 struct Library *libBase);
-
- /* Message sender for the above patches */
- BOOL ATESendMsg(struct ATEMessage *ateMsg);
-
- /* A couple of dead functions not in here anymore */
- // struct FontNode *SwapSoftStyle(struct RastPort *rp);
- // void UndoSwapSoftStyle(struct RastPort *rp, struct TextFont *tf, UBYTE softStyle);
-
- /* Functions for the PostScript interface and tracing */
- void PSTrace(char *format, ...);
- void PSIntf(char *format, ...);
-
- /* Functions to simplify some loops, these do most of the PostScript gruntwork */
- struct TextFont *MakeATEFont(struct FontNode *fontNode, struct TextAttr *textAttr);
- BOOL MakeATEChars(struct FontNode *fontNode);
-
- /* Functions from older versions of ATEServer (with a new one: AddATEStyle) */
- void chkabort(void) { return; }; /* Kill CTRL-C handler */
- void ClearFontNames(struct List *fontList);
- BOOL AddATEFont(struct List *fontList, struct DiskfontMsg *diskfontMsg);
- BOOL AddATEStyle(struct List *fontList, struct SSStyleMsg *sssMsg);
- BOOL AddATEChars(struct List *fontList, struct TextMsg *textMsg);
- struct DiskFontHeader *BuildScaledDiskFont(struct TextFont *textFont, struct TextAttr *textAttr);
- void ClearUnusedATEFonts(struct FontList *fontList);
-
- /* One fcn which is the main process */
- int ATEmain(struct Task *callingTask, BYTE okSigBit, BYTE failSigBit);
-
- /* external file handle for ATE output */
- FILE *ateOutput;
-
- /* wbmain() entry point, supposed to read tooltypes and start ATE
- with tooltypes options. In future will include a user interface
- and perhaps become a commodity */
-
- int wbmain(struct WBStartup *wbMsg)
- {
- struct MsgPort *ateCmdPort;
- char *ateCmdPortName = "ATE_Cmd_Port";
- int exitCode;
- char *argv[2];
- struct CommandMsg *ateCmdMsg;
- BOOL ateStartSuccess;
-
- /* Ok, this makes one VERY BIG assumption that the msgport won't go away
- after I find it. This makes sense because the only way you can
- break ATE is to send an exit message to it. */
- Forbid();
- ateCmdPort = FindPort(ateCmdPortName);
- Permit();
-
- if (ateCmdPort == 0)
- {
- /* Since this was run from Workbench or WBStartup, I can run
- ATE without having to detach from anything. */
- ateOutput = fopen("CON:0/0/600/75/ATE Message/AUTO/WAIT", "w");
- if (ateOutput != 0)
- {
- // fprintf(ateOutput, "Starting ATE... when you see ATE Ready you can close this window.\n");
- // fprintf(ateOutput, "Double-click this icon again to exit ATE.\n");
- fflush(ateOutput);
- exitCode = ATEmain(0, 0, 0);
- /* This will immediately exit upon returning from ATEmain() */
- fclose(ateOutput);
- return(exitCode);
- }
- }
- else
- {
- /* Send -exit parameter to ATE, but first build the thing */
- ateCmdMsg = (struct CommandMsg *)AllocVec(sizeof(struct CommandMsg) + 64, MEMF_PUBLIC | MEMF_CLEAR);
- if (ateCmdMsg != 0)
- {
- argv[0] = (char *)&ateCmdMsg[1];
- argv[1] = argv[0] + 32;
- strcpy(argv[1], "-exit");
- strcpy(argv[0], "ATEbeta5");
- ateCmdMsg->cm_ATEMsg.ate_MsgLength = sizeof(struct CommandMsg);
- ateCmdMsg->cm_ATEMsg.ate_DestPort = ateCmdPort;
- ateCmdMsg->cm_ArgC = 2;
- ateCmdMsg->cm_ArgV = argv;
- ateStartSuccess = ATESendMsg((struct ATEMessage *)ateCmdMsg);
- if (ateStartSuccess == FALSE)
- exitCode = 20;
- else
- exitCode = 0;
- FreeVec(ateCmdMsg);
- }
- }
- return(exitCode);
- }
-
- /* command line entry point, looks for an existing port and passes
- arguments to it, otherwise it starts the ATE mainline */
-
- int main(int argc, char *argv[])
- {
- struct MsgPort *ateCmdPort;
- struct CommandMsg *ateCmdMsg;
- char *ateCmdPortName = "ATE_Cmd_Port";
- char startAteCmdLine[80];
- BOOL ateStartSuccess;
- int exitCode = 0;
- struct Task *callingTask = (struct Task *)0;
- BYTE okSigBit, failSigBit;
- ULONG okSig, failSig, signal;
-
- /* Ok, this makes one VERY BIG assumption that the msgport won't go away
- after I find it. This makes sense because the only way you can
- break ATE is to send an exit message to it. */
- Forbid();
- ateCmdPort = FindPort(ateCmdPortName);
- Permit();
-
- if (ateCmdPort == 0)
- {
- /* Check for "-start" parameter, if so, call ATEmain() */
- if (argc > 1)
- {
- if (strcmp(argv[1], "-start") == 0)
- {
- ateOutput = fopen("CON:0/0/600/75/ATE Message/AUTO/WAIT", "w");
- if (ateOutput != 0)
- {
- callingTask = (struct Task *)atoi(argv[2]);
- okSigBit = (BYTE)atoi(argv[3]);
- failSigBit = (BYTE)atoi(argv[4]);
- exitCode = ATEmain(callingTask, okSigBit, failSigBit);
- /* This will immediately exit upon returning from ATEmain() */
- fclose(ateOutput);
- return(exitCode);
- }
- }
- }
- /* No message port found, send command with "-start" parameter */
- callingTask = FindTask(0);
- okSigBit = AllocSignal(-1);
- failSigBit = AllocSignal(-1);
-
- sprintf(startAteCmdLine, "Run >nil: <nil: %s -start %d %d %d",
- argv[0], callingTask, okSigBit, failSigBit);
-
- ateStartSuccess = Execute(startAteCmdLine, 0, 0);
- if (ateStartSuccess == FALSE)
- exitCode = 20;
- else
- {
- printf("ATE started... type %s -exit to terminate ATE.\n", argv[0]);
- printf("Amiga Typeface Engine BETA 1.5\n");
-
- /* Now wait on the signals then send parameters */
-
- okSig = 1 << okSigBit;
- failSig = 1 << failSigBit;
- signal = Wait(okSig | failSig);
-
- if (signal & okSig)
- {
- exitCode = 0;
- /* Obtain the new port ptr now */
- Forbid();
- ateCmdPort = FindPort(ateCmdPortName);
- Permit();
- }
- else
- exitCode = 20;
- FreeSignal(okSigBit);
- FreeSignal(failSigBit);
- }
- }
- if (argc > 1 && exitCode == 0)
- {
- /* There's an active ATE now running, pass parameters to it */
- ateCmdMsg = (struct CommandMsg *)AllocVec(sizeof(struct CommandMsg), MEMF_PUBLIC | MEMF_CLEAR);
- if (ateCmdMsg != 0 && ateCmdPort != 0)
- {
- ateCmdMsg->cm_ATEMsg.ate_MsgLength = sizeof(struct CommandMsg);
- ateCmdMsg->cm_ATEMsg.ate_DestPort = ateCmdPort;
- ateCmdMsg->cm_ArgC = argc;
- ateCmdMsg->cm_ArgV = argv;
- ateStartSuccess = ATESendMsg((struct ATEMessage *)ateCmdMsg);
- if (ateStartSuccess == FALSE)
- {
- printf("No active ATE to send messages to...\n");
- exitCode = 20;
- }
- else
- {
- printf("Updated parameters sent OK\n");
- exitCode = 0;
- }
- FreeVec(ateCmdMsg);
- }
- else
- {
- if (ateCmdMsg == 0)
- printf("Not enough memory to send any messages\n");
- if (ateCmdPort == 0)
- printf("No active ATE to send messages to.\n");
- ateStartSuccess = FALSE;
- exitCode = 20;
- }
- }
- else if (callingTask == 0)
- {
- printf( "ATE Beta 5 already active\n"
- "Usage: %s -arguments\n"
- "================================\n"
- "-(no)trace Hide or Show trace messages in code, default NO\n"
- "-(no)debug Hide or Show all PS commands executed, default NO\n"
- "-hidediskfonts Show only loaded fonts and ATE fonts to apps\n"
- "-showdiskfonts Show all Amiga and ATE fonts to apps (default)\n"
- "-softstyleson Enable algorithmic styles on ATE fonts\n"
- "-softstylesoff Disable algorithmic styles on ATE fonts (default)\n"
- "-availfonts SM SI Show what sizes of ATE fonts appear in lists\n"
- " SM = size maximum, SI = size increment\n"
- " 72 and 6 default, shows sizes\n"
- " 6 12 18 24 30 36 42 48 54 60 66 72\n"
- "-dpi DPI Change display resolution of ATE fonts\n"
- " DPI = dots per inch on screen. Default 72\n"
- " Must close all apps using ATE before using -dpi\n"
- "-exit Unloads all ATE fonts and exits ATE\n"
- " Must close all apps using ATE before using -exit\n"
- "================================\n"
- "You can use many arguments on the same command line.\n"
- "All arguments work in startup as well.\n", argv[0]);
- exitCode = 0;
- }
- return(exitCode);
- }
-
- /* Mainline of code */
- int ATEmain(struct Task *callingTask, BYTE okSigBit, BYTE failSigBit)
- {
- APTR oldFuncPtr, newFuncPtr = &NewOpenDiskFont;
- APTR oldTextPtr, newTextPtr = &NewText;
- APTR oldSSSPtr, newSSSPtr = &NewSSStyle;
- APTR oldAFPtr, newAFPtr = &NewAvailFonts;
- APTR oldDFEPtr, newDFEPtr = &NewDFbaseExpunge;
- APTR oldNSDFPtr, newNSDFPtr = &NewNSDF;
- // APTR oldTLPtr, newTLPtr = &NewTextLength;
- // APTR oldTEPtr, newTEPtr = &NewTextExtent;
- char *versionInfo = "$VER: AmigaTypeEngine_BETA 1.5 (13.8.95)";
- char *moreInfo = "Written by Gordon Fecyk of Winnipeg / Calgary / Vancouver :)";
- struct MsgPort *ateCmdPort;
- struct CommandMsg *commandMsg;
- struct List *fontList;
- struct SignalSemaphore *ateSemaphore, *nafSemaphore = &aafSemaphore;
- struct DiskfontMsg *diskfontMsg;
- struct TextMsg *textMsg;
- struct SSStyleMsg *sssMsg;
- struct NsdfMsg *nsdfMsg;
- ULONG signal, odfSig, textSig, sssSig, cmdSig, dfeSig, nsdfSig;
- BOOL keepGoing = TRUE;
- FILE *encodingFile, *nilInput;
- int index, asciiValue, openCount, diskfontSize;
- char readLine[100], charName[32];
-
- optTrace = FALSE;
- optDebug = FALSE;
- optSoftStyles = FALSE;
- defaultDPI = 72;
- /* Do as much allocating as practical then check for failures */
- /* Message ports */
- ateODFPort = CreateMsgPort();
- ateTextPort = CreateMsgPort();
- ateSSSPort = CreateMsgPort();
- ateCmdPort = CreateMsgPort();
- ateNSDFPort = CreateMsgPort();
- ateDfeSigBit = AllocSignal(-1);
- /* ATE font list */
- ateFontList = (struct ATEFontList *)AllocVec(sizeof(struct ATEFontList), MEMF_PUBLIC | MEMF_CLEAR);
- /* post.library (minimum V15) */
- PSbase = OpenLibrary("post.library", 15L);
- /* graphics and diskfont libraries (mininum V36) */
- diskfontBase = OpenLibrary("diskfont.library", 36L);
- gfxBase = OpenLibrary("graphics.library", 36L);
- diskfontSize = AvailFonts(readLine, 0, AFF_DISK | AFF_TAGGED);
- ateAvailFonts = PrepATEAvailFonts(72, 6, diskfontSize);
- psParm = (struct PSparm *)AllocVec(sizeof(struct PSparm), MEMF_PUBLIC | MEMF_CLEAR);
-
- /* check for failures */
- if (ateODFPort == 0 || ateTextPort == 0 || ateSSSPort == 0 || ateCmdPort == 0
- || PSbase == 0 || gfxBase == 0 || diskfontBase == 0 || ateDfeSigBit == -1
- || ateFontList == 0 || ateAvailFonts == 0 || psParm == 0 || ateNSDFPort == 0)
- {
- if (ateNSDFPort != 0)
- DeleteMsgPort(ateNSDFPort);
- else
- fprintf(ateOutput, "Error allocatine one message port\n");
- if (psParm != 0)
- FreeVec(psParm);
- else
- fprintf(ateOutput, "Error allocating RAM for PS struct \n");
- if (ateDfeSigBit != -1)
- FreeSignal(ateDfeSigBit);
- else
- fprintf(ateOutput, "Error obtaining a signal bit\n");
- if (ateCmdPort != 0)
- DeleteMsgPort(ateCmdPort);
- else
- fprintf(ateOutput, "Error opening command port\n");
- if (ateAvailFonts != 0)
- FreeVec(ateAvailFonts);
- else
- fprintf(ateOutput, "Error obtaining memory for ATEAvailFonts\n");
- if (ateSSSPort != 0)
- DeleteMsgPort(ateSSSPort);
- else
- fprintf(ateOutput, "Error opening one message port\n");
- if (ateODFPort != 0)
- DeleteMsgPort(ateODFPort);
- else
- fprintf(ateOutput, "Error opening one message port\n");
- if (ateTextPort != 0)
- DeleteMsgPort(ateTextPort);
- else
- fprintf(ateOutput, "Error opening one message port\n");
- if (PSbase != 0)
- CloseLibrary(PSbase);
- else
- fprintf(ateOutput, "Error opening post.library\n"
- "You require V15 post.library\n");
- if (ateFontList != 0)
- FreeVec(ateFontList);
- else
- fprintf(ateOutput, "Error allocating RAM for fontList\n");
- if (gfxBase != 0)
- CloseLibrary(gfxBase);
- else
- fprintf(ateOutput, "Error opening graphics.library\n");
- if (diskfontBase != 0)
- CloseLibrary(diskfontBase);
- else
- fprintf(ateOutput, "Error opening diskfont.library\n"
- "This requires at least WB 2.04\n");
- if (callingTask != 0)
- Signal(callingTask, 1 << failSigBit);
- return(20);
- }
-
- /* initalize the PostScript activation */
- PSTrace("%%Initalizing PostScript Activation\n");
- psParm->page.buf[0] = nameBuffer;
- psParm->page.len = 100;
- psParm->page.depth = 1;
- psParm->page.xbytes = 10;
- psParm->page.xsize = 80;
- psParm->page.ysize = 10;
- psParm->page.xden = 72;
- psParm->page.yden = 72;
- psParm->page.ydir = -1;
- psParm->memvlen = 20000;
- psParm->memflen = 10000;
- psParm->memllen = defmemllen;
- psParm->memhlen = minmemhlen;
- /* This must be a real file handle (IE: "NIL:" in Beta 5) */
- nilInput = fopen("nil:", "r");
- psParm->infh = fdtofh(nilInput);
- psParm->outfh = fdtofh(ateOutput);
- psParm->errfh = fdtofh(ateOutput);
- /* I'm getting lazy... I like MEMF_CLEAR... :) */
-
- psActivation = PScreateact(psParm);
- if (psActivation <= errmax)
- {
- fprintf(ateOutput, "PostScript activation failed\n");
- DeleteMsgPort(ateNSDFPort);
- DeleteMsgPort(ateODFPort);
- DeleteMsgPort(ateTextPort);
- DeleteMsgPort(ateSSSPort);
- DeleteMsgPort(ateCmdPort);
- FreeSignal(ateDfeSigBit);
- FreeVec(psParm);
- FreeVec(ateFontList);
- FreeVec(ateAvailFonts);
- CloseLibrary(PSbase);
- CloseLibrary(gfxBase);
- CloseLibrary(diskfontBase);
- if (callingTask != 0)
- Signal(callingTask, 1 << failSigBit);
- return(20);
- }
-
- /* Run ATE startup files */
- PSTrace("%%All initalization passed, running PS startup & encoding files\n");
- PSIntf("(%.100s) run clear\n", "PSFonts:init.ps");
- if (psError != 0)
- {
- fprintf(ateOutput, "Error running initalization file,\n"
- "check your PSFonts:init.ps file.\n");
- }
-
- PSIntf("/encoding StandardEncoding 256 array copy def\n");
- PSIntf("[ (%.100s) run] aload length 2 idiv\n", "PSFonts:ATEencoding.ps");
- PSIntf("{ encoding 3 1 roll put } repeat\n");
- PSIntf("/cstr 1 string def\n");
- if (psError != 0)
- {
- fprintf(ateOutput, "Error running initalization file,\n"
- "check your PSFonts:ATEencoding.ps file.\n");
- }
-
- /* Read encoding file into memory */
- encodingFile = fopen("PSFonts:ATEencoding.ps", "r");
- if (encodingFile != 0)
- {
- while (!feof(encodingFile))
- {
- asciiValue = 0;
- charName[0] = 0;
- readLine[0] = 0;
- fgets(readLine, 100, encodingFile);
- sscanf(readLine, "%3d /%s\n", &asciiValue, charName);
- if (asciiValue != 0)
- {
- strcpy(encodingExternal[asciiValue], charName);
- }
- }
- }
- if (psError != 0 || encodingFile == 0)
- {
- fprintf(ateOutput, "Cannot parse ATEencoding.ps file\n");
- if (encodingFile != 0)
- fclose(encodingFile);
- DeleteMsgPort(ateNSDFPort);
- DeleteMsgPort(ateODFPort);
- DeleteMsgPort(ateTextPort);
- DeleteMsgPort(ateSSSPort);
- DeleteMsgPort(ateCmdPort);
- FreeSignal(ateDfeSigBit);
- FreeVec(psParm);
- FreeVec(ateFontList);
- FreeVec(ateAvailFonts);
- CloseLibrary(PSbase);
- CloseLibrary(gfxBase);
- CloseLibrary(diskfontBase);
- if (callingTask != 0)
- Signal(callingTask, 1 << failSigBit);
- return(20);
- }
- fclose(encodingFile);
-
- // fprintf(ateOutput, "Number of unique typefaces %d\n", ateAvailFonts->aaf_NumNames);
-
- /* Setup ports */
- odfSig = 1 << ateODFPort->mp_SigBit;
- textSig = 1 << ateTextPort->mp_SigBit;
- sssSig = 1 << ateSSSPort->mp_SigBit;
- cmdSig = 1 << ateCmdPort->mp_SigBit;
- nsdfSig = 1 << ateNSDFPort->mp_SigBit;
- dfeSig = 1 << ateDfeSigBit;
- ateODFPort->mp_Node.ln_Pri = 0;
- ateTextPort->mp_Node.ln_Pri = 0;
- ateSSSPort->mp_Node.ln_Pri = 0;
- ateCmdPort->mp_Node.ln_Pri = 0;
- ateNSDFPort->mp_Node.ln_Pri = 0;
- ateCmdPort->mp_Node.ln_Name = "ATE_Cmd_Port";
- AddPort(ateCmdPort);
- /* prepare list */
- fontList = &ateFontList->fontList;
- fontList->lh_Type = NT_USER;
- NewList(fontList);
- /* Prepare semaphores */
- ateSemaphore = &ateFontList->ateSemaphore;
- InitSemaphore(ateSemaphore);
- InitSemaphore(nafSemaphore);
- // fprintf(ateOutput, "ATE BETA 1.5 ready.\n");
- fflush(ateOutput);
- /* Grab the task ptr for the DFE signals */
- ateMainTask = FindTask(0);
-
- /* Perform patches */
- Forbid();
- oldFuncPtr = SetFunction(diskfontBase, -0x1E, newFuncPtr);
- OldOpenDiskFont = oldFuncPtr;
- oldTextPtr = SetFunction(gfxBase, -0x3C, newTextPtr);
- OldText = oldTextPtr;
- oldSSSPtr = SetFunction(gfxBase, -0x5A, newSSSPtr);
- OldSSStyle = oldSSSPtr;
- oldAFPtr = SetFunction(diskfontBase, -0x24, newAFPtr);
- OldAvailFonts = oldAFPtr;
- oldDFEPtr = SetFunction(diskfontBase, -0x12, newDFEPtr);
- OldDFbaseExpunge = oldDFEPtr;
- oldNSDFPtr = SetFunction(diskfontBase, -0x36, newNSDFPtr);
- OldNSDF = oldNSDFPtr;
- // oldTLPtr = SetFunction(gfxBase, -0x36, newTLPtr);
- // OldTextLength = oldTLPtr;
- // oldTEPtr = SetFunction(gfxBase, -0x2B2, newTEPtr);
- // OldTextExtent = oldTEPtr;
- Permit();
- /* I got the offsets from the included pragmas files. */
-
- /* Signal the calling process we're ready */
- if (callingTask != 0)
- Signal(callingTask, 1 << okSigBit);
-
- /* Begin main process loop */
- for (;;)
- {
- signal = Wait (textSig | odfSig | sssSig | dfeSig | cmdSig | nsdfSig);
-
- if ((signal & cmdSig))
- {
- /* Someone sent a command here. */
- while (commandMsg = (struct CommandMsg *)GetMsg(ateCmdPort))
- {
- if (commandMsg->cm_ArgC <= 1)
- {
- fprintf(ateOutput, "No parameters sent with command \n");
- }
- /* Several if() statements happen here for each parameter */
- else for (index = 1; index < commandMsg->cm_ArgC; index++)
- {
- if (strcmp(commandMsg->cm_ArgV[index], "-exit") == 0)
- {
- keepGoing = FALSE;
- break;
- }
- /* More if () statements for each argument
- happen here, and mods happen accordingly */
- if (strcmp(commandMsg->cm_ArgV[index], "-trace") == 0)
- optTrace = TRUE;
- if (strcmp(commandMsg->cm_ArgV[index], "-notrace") == 0)
- optTrace = FALSE;
- if (strcmp(commandMsg->cm_ArgV[index], "-debug") == 0)
- optDebug = TRUE;
- if (strcmp(commandMsg->cm_ArgV[index], "-nodebug") == 0)
- optDebug = FALSE;
- if (strcmp(commandMsg->cm_ArgV[index], "-availfonts") == 0)
- {
- /* Make sure these are valid parameters */
- int sizeMax, sizeInc, mySizeDiskFonts;
-
- index++;
- if (index < commandMsg->cm_ArgC)
- sizeMax = atoi(commandMsg->cm_ArgV[index]);
- else
- sizeMax = 0;
- index++;
- if (index < commandMsg->cm_ArgC)
- sizeInc = atoi(commandMsg->cm_ArgV[index]);
- else
- sizeInc = 0;
-
- if (sizeMax > sizeInc && sizeInc > 0)
- {
- /* make the call */
- ObtainSemaphore(nafSemaphore);
- mySizeDiskFonts = ateAvailFonts->aaf_SizeDiskFonts;
- FreeVec(ateAvailFonts);
- ateAvailFonts = 0;
- ateAvailFonts = PrepATEAvailFonts(sizeMax, sizeInc, mySizeDiskFonts);
- if (ateAvailFonts == 0)
- {
- fprintf(ateOutput, "Warning: System extremely low on memory\n");
- fflush(ateOutput);
- keepGoing = FALSE;
- }
- ReleaseSemaphore(nafSemaphore);
- }
- else
- {
- fprintf(ateOutput, "Usage for -availfonts:\n"
- "-availfonts sizemax sizeinc\n");
- fflush(ateOutput);
- }
- }
- if (strcmp(commandMsg->cm_ArgV[index], "-dpi") == 0)
- {
- /* Make sure these are valid parameters */
- int newDpi, sizeInc, sizeMax, mySizeDiskFonts;
-
- index++;
- if (index < commandMsg->cm_ArgC)
- newDpi = atoi(commandMsg->cm_ArgV[index]);
- else
- newDpi = 0;
- if (newDpi > 49)
- {
- /* check opencount */
- openCount = CountOpenFonts();
- if (openCount == 0)
- {
- ClearUnusedATEFonts(fontList);
- defaultDPI = newDpi;
- /* reset ATEAvailFonts */
- ObtainSemaphore(nafSemaphore);
- mySizeDiskFonts = ateAvailFonts->aaf_SizeDiskFonts;
- sizeInc = ateAvailFonts->aaf_SizeInc;
- sizeMax = ateAvailFonts->aaf_SizeMax;
- FreeVec(ateAvailFonts);
- ateAvailFonts = 0;
- ateAvailFonts = PrepATEAvailFonts(sizeMax, sizeInc, mySizeDiskFonts);
- if (ateAvailFonts == 0)
- {
- fprintf(ateOutput, "Warning: System extremely low on memory\n");
- fflush(ateOutput);
- keepGoing = FALSE;
- }
- ReleaseSemaphore(nafSemaphore);
- }
- else
- {
- fprintf(ateOutput,
- "Cannot change default DPI unless you close all apps\n"
- "using ATE fonts.\n");
- fflush(ateOutput);
- }
- }
- else
- {
- fprintf(ateOutput, "DPI choice set too small, use DPI greater than 50.\n");
- fflush(ateOutput);
- }
- }
- if (strcmp(commandMsg->cm_ArgV[index], "-hidediskfonts") == 0)
- {
- ObtainSemaphore(nafSemaphore);
- /* First check to see if diskfonts are
- already hidden */
- if (ateAvailFonts->aaf_SizeDiskFonts != 0)
- {
- int sizeMax, sizeInc;
-
- sizeMax = ateAvailFonts->aaf_SizeMax;
- sizeInc = ateAvailFonts->aaf_SizeInc;
- FreeVec(ateAvailFonts);
- ateAvailFonts = 0;
- ateAvailFonts = PrepATEAvailFonts(sizeMax, sizeInc, 0);
- if (ateAvailFonts == 0)
- {
- fprintf(ateOutput, "Warning: System extremely low on memory\n");
- fflush(ateOutput);
- keepGoing = FALSE;
- }
- }
- else
- {
- fprintf(ateOutput, "Amiga diskfonts already hidden. No changes made.\n");
- fflush(ateOutput);
- }
- ReleaseSemaphore(nafSemaphore);
- }
- if (strcmp(commandMsg->cm_ArgV[index], "-showdiskfonts") == 0)
- {
- ObtainSemaphore(nafSemaphore);
- /* Check to see if we're already showing diskfonts */
- if (ateAvailFonts->aaf_SizeDiskFonts == 0)
- {
- int mySizeDiskFonts, sizeMax, sizeInc;
-
- sizeMax = ateAvailFonts->aaf_SizeMax;
- sizeInc = ateAvailFonts->aaf_SizeInc;
-
- mySizeDiskFonts = OldAvailFonts(readLine, 0, AFF_DISK | AFF_TAGGED, diskfontBase);
- ateAvailFonts = 0;
- ateAvailFonts = PrepATEAvailFonts(sizeMax, sizeInc, mySizeDiskFonts);
- if (ateAvailFonts == 0)
- {
- fprintf(ateOutput, "Warning: System extremely low on memory\n");
- fflush(ateOutput);
- keepGoing = FALSE;
- }
- }
- else
- {
- fprintf(ateOutput, "Amiga diskfonts already visible. No changes made.\n");
- fflush(ateOutput);
- }
- ReleaseSemaphore(nafSemaphore);
- }
- if (strcmp(commandMsg->cm_ArgV[index], "-softstyleson") == 0)
- optSoftStyles = TRUE;
- if (strcmp(commandMsg->cm_ArgV[index], "-softstylesoff") == 0)
- optSoftStyles = FALSE;
- }
- ReplyMsg((struct Message *)commandMsg);
- }
- }
-
- if (keepGoing == FALSE)
- {
- /* check open count */
- openCount = CountOpenFonts();
- if (openCount != 0)
- {
- fprintf(ateOutput, "WARNING: Some apps have ATE fonts in use!\n"
- "Either close all apps using ATE fonts and try again,\n"
- "or simply reboot (ATE won't cause data loss).\n");
- fprintf(ateOutput, "ATE open font count: %d\n", openCount);
- fflush(ateOutput);
- keepGoing = TRUE;
- }
- else
- {
- RemPort(ateCmdPort);
- /* Clear out all ports */
- while (diskfontMsg = (struct DiskfontMsg *)GetMsg(ateODFPort))
- {
- diskfontMsg->df_ATEFont = FALSE;
- ReplyMsg((struct Message *)diskfontMsg);
- }
- while (textMsg = (struct textMsg *)GetMsg(ateTextPort))
- {
- textMsg->tm_ATEFont = FALSE;
- ReplyMsg((struct Message *)textMsg);
- }
- while (sssMsg = (struct sssMsg *)GetMsg(ateSSSPort))
- {
- sssMsg->ss_ATEFont = FALSE;
- ReplyMsg((struct Message *)sssMsg);
- }
- while (commandMsg = (struct CommandMsg *)GetMsg(ateCmdPort))
- {
- ReplyMsg((struct Message *)commandMsg);
- }
- while (nsdfMsg = (struct NSDFMsg *)GetMsg(ateNSDFPort))
- {
- ReplyMsg((struct Message *)nsdfMsg);
- }
- keepGoing = FALSE;
- break;
- }
- }
- if ((signal & dfeSig))
- {
- ClearUnusedATEFonts(fontList);
- SetSignal(0, dfeSig);
- }
- if (signal & nsdfSig)
- {
- while (nsdfMsg = (struct NsdfMsg *)GetMsg(ateNSDFPort))
- {
- nsdfMsg->nsdf_DFHeader = BuildScaledDiskFont(nsdfMsg->nsdf_TextFont, nsdfMsg->nsdf_TextAttr);
- ReplyMsg((struct Message *)nsdfMsg);
- }
- }
- if ((signal & textSig))
- {
- while (textMsg = (struct TextMsg *)GetMsg(ateTextPort))
- {
- keepGoing = AddATEChars(fontList, textMsg);
- if (keepGoing == FALSE)
- {
- PSTrace("%%Out of memory or some other error drawing new chars\n");
- psError = 0;
- }
- keepGoing = TRUE;
- ReplyMsg((struct Message *)textMsg);
- }
- }
- if ((signal & odfSig))
- {
- while (diskfontMsg = (struct DiskfontMsg *)GetMsg(ateODFPort))
- {
- keepGoing = AddATEFont(fontList, diskfontMsg);
- if (keepGoing == FALSE)
- {
- PSTrace("%%Out of memory creating new textfont\n");
- psError = 0;
- }
- keepGoing = TRUE;
- ReplyMsg((struct Message *)diskfontMsg);
- }
- }
- if ((signal & sssSig))
- {
- while (sssMsg = (struct SSStyleMsg *)GetMsg(ateSSSPort))
- {
- keepGoing = AddATEStyle(fontList, sssMsg);
- if (keepGoing == FALSE)
- {
- PSTrace("%%Out of memory creating new textfont for new style\n");
- psError = 0;
- }
- keepGoing = TRUE;
- ReplyMsg((struct Message *)sssMsg);
- }
- }
- }
-
- /* Clean up time */
- Forbid();
- /* There is a proper way to undo these, but I'm too lazy */
- newNSDFPtr = SetFunction(diskfontBase, -0x36, oldNSDFPtr);
- newFuncPtr = SetFunction(diskfontBase, -0x1E, oldFuncPtr);
- newTextPtr = SetFunction(gfxBase, -0x3C, oldTextPtr);
- newSSSPtr = SetFunction(gfxBase, -0x5A, oldSSSPtr);
- newAFPtr = SetFunction(diskfontBase, -0x24, oldAFPtr);
- newDFEPtr = SetFunction(diskfontBase, -0x12, oldDFEPtr);
- // newTLPtr = SetFunction(gfxBase, -0x36, oldTLPtr);
- // newTEPtr = SetFunction(gfxBase, -0x2B2, oldTEPtr);
- Permit();
- fprintf(ateOutput, "Patches removed, cleaning up...");
- DeleteMsgPort(ateCmdPort);
- DeleteMsgPort(ateODFPort);
- DeleteMsgPort(ateTextPort);
- DeleteMsgPort(ateSSSPort);
- DeleteMsgPort(ateNSDFPort);
- FreeSignal(ateDfeSigBit);
- ClearFontNames(fontList);
- ObtainSemaphore(ateSemaphore);
- ReleaseSemaphore(ateSemaphore);
- FreeVec(ateFontList);
- ObtainSemaphore(nafSemaphore);
- ReleaseSemaphore(nafSemaphore);
- FreeVec(ateAvailFonts);
- fclose(nilInput);
- PSdeleteact(psActivation);
- FreeVec(psParm);
- CloseLibrary(PSbase);
- CloseLibrary(gfxBase);
- CloseLibrary(diskfontBase);
-
- fprintf(ateOutput, "Now exiting.\nRemember: This is BETA software! Use at own risk!\n");
- return(0);
- }
-
- void ClearFontNames(struct List *fontList)
- {
- struct FontNode *workNode, *nextNode;
- struct SignalSemaphore *ateSemaphore = &ateFontList->ateSemaphore;
-
- ObtainSemaphore(ateSemaphore);
- workNode = (struct FontNode *)(fontList->lh_Head);
- while (nextNode = (struct FontNode *)(workNode->fn_Node.ln_Succ))
- {
- if (workNode->fn_TextFont != 0)
- {
- RemFont(workNode->fn_TextFont);
- StripFont(workNode->fn_TextFont);
- FreeMem(workNode->fn_ExtDFHeader, workNode->fn_ExtDFHeader->edf_Length);
- // FreeVec(workNode->fn_TextFont);
- }
- FreeVec(workNode);
- workNode = nextNode;
- }
- ReleaseSemaphore(ateSemaphore);
- return;
- }
-
- BOOL AddATEChars(struct List *fontList, struct TextMsg *textMsg)
- {
- struct FontNode *fontNode;
- char *builtChars;
- STRPTR oneChar;
- UBYTE indexY;
- BOOL callMakeATEChars = FALSE;
- BOOL addATECharsOK;
- WORD indexX, length;
-
- /* Needed fontnode already found by the Text() patch. */
-
- fontNode = textMsg->tm_FontNode;
-
- if (fontNode != 0)
- {
- /* begin pre-scan, determine what chars really need to be drawn */
- length = textMsg->tm_Length;
- builtChars = fontNode->fn_BuiltChars;
- oneChar = (textMsg->tm_Chars);
- for (indexX = 0; indexX < length; indexX++)
- {
- /* Mark needed characters */
- indexY = oneChar[indexX];
- if (builtChars[indexY] == CHAR_NOT_DRAWN)
- {
- builtChars[indexY] = CHAR_NEEDED;
- callMakeATEChars = TRUE;
- }
- }
- textMsg->tm_ATEFont = TRUE;
- addATECharsOK = TRUE;
- if (callMakeATEChars == TRUE)
- {
- addATECharsOK = MakeATEChars(fontNode);
- }
- }
- else
- {
- textMsg->tm_ATEFont = FALSE;
- addATECharsOK = TRUE;
- }
-
- return(addATECharsOK);
- }
-
- BOOL AddATEFont(struct List *fontList, struct DiskfontMsg *diskfontMsg)
- {
- struct TextAttr *textAttr;
- struct TTextAttr *taggedTextAttr;
- struct FontNode *fontNode;
- struct SignalSemaphore *ateSemaphore = &ateFontList->ateSemaphore;
- UBYTE fontStyle;
- char fontName[64], regularName[64], typefaceName[64];
- char dummyString[80], *dotPtr, optFontEncoding;
- BOOL addATEFontOK;
- FILE *ateFile;
- int lowChar, highChar;
- float xDPI, yDPI;
- float dpiRatio;
- struct TagItem *dpiTag;
- ULONG dpiData;
-
- textAttr = diskfontMsg->df_TextAttr;
- if (textAttr->ta_Style & FSF_TAGGED)
- taggedTextAttr = (struct TTextAttr *)textAttr;
- else
- taggedTextAttr = 0;
-
- /* Make sure the font in question is an ATE font. */
- strcpy(fontName, "FONTS:");
- strcat(fontName, textAttr->ta_Name);
- dotPtr = strchr(fontName, '.');
- *dotPtr = '\0';
- /* OK try opening the file */
- ateFile = fopen(fontName, "r");
- if (ateFile == 0)
- {
- diskfontMsg->df_ATEFont = FALSE;
- return(TRUE);
- /* hey, not an ATE-ready typeface so exit */
- }
- /* Now search to see if requested font already exists */
- textAttr = diskfontMsg->df_TextAttr;
- fontStyle = textAttr->ta_Style & (FSF_BOLD | FSF_ITALIC);
- sprintf(fontName, "%50s / %5d / %2x", textAttr->ta_Name, textAttr->ta_YSize, fontStyle);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, fontName);
- ReleaseSemaphore(ateSemaphore);
- if (fontNode != 0)
- {
- diskfontMsg->df_ATEFont = TRUE;
- diskfontMsg->df_TextFont = fontNode->fn_TextFont;
- return(TRUE);
- /* Hey, why work if you already have results? */
- }
-
- /* NOTE: ATE can only worry about substituting bold or italic versions, */
- /* setting soft styles will take care of underlining */
-
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "%c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(regularName, dotPtr);
- strcpy(typefaceName, regularName);
- switch(fontStyle)
- {
- case 0x02:
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- case 0x04:
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- case 0x06:
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- default:
- break;
- }
-
- fclose(ateFile);
- /* If no real typeface exists for desired style, use plain style */
- if (strcmp(typefaceName, regularName) == 0)
- fontStyle = FS_NORMAL;
-
- /* Build search string and see if we don't already have this font */
- sprintf(fontName, "%50s / %5d / %2x", textAttr->ta_Name, textAttr->ta_YSize, fontStyle);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, fontName);
- ReleaseSemaphore(ateSemaphore);
- if (fontNode != 0)
- {
- diskfontMsg->df_ATEFont = TRUE;
- diskfontMsg->df_TextFont = fontNode->fn_TextFont;
- return(TRUE);
- /* Hey, why work if you already have results? */
- }
-
- /* Original OpenDiskFont takes over here. If the TA_DeviceDPI
- don't match, tough luck as per C= spec. */
-
- dpiData = 0;
- /* So no font node eh? Time to make one. */
- if (taggedTextAttr != 0)
- {
- dpiTag = taggedTextAttr->tta_Tags;
- dpiData = GetTagData(TA_DeviceDPI, 0L, dpiTag);
-
- if (dpiData != 0)
- {
- xDPI = (dpiData & 0xFFFF0000) >> 16;
- yDPI = dpiData & 0x0000FFFF;
- dpiRatio = xDPI / yDPI;
- PSTrace("Typeface DPI: %d x, %d y\n", xDPI, yDPI);
- PSTrace("DPI ratio: %f\n", dpiRatio);
- }
-
- }
-
- /* Consider a function to allocate the entire node and TextFont too */
- fontNode = (struct FontNode *)AllocVec(sizeof(struct FontNode), MEMF_PUBLIC | MEMF_CLEAR);
- if (fontNode != 0)
- {
- strcpy(fontNode->fn_Name, fontName);
- fontNode->fn_Node.ln_Name = fontNode->fn_Name;
- fontNode->fn_Node.ln_Type = NT_USER;
- fontNode->fn_Node.ln_Pri = 0;
- strcpy(fontNode->fn_TypefaceName, typefaceName);
- dotPtr = strchr(fontNode->fn_TypefaceName, '\n');
- if (dotPtr != 0)
- *dotPtr = 0;
- fontNode->fn_LowChar = lowChar;
- fontNode->fn_HighChar = highChar;
- fontNode->fn_OptFontEncoding = optFontEncoding;
- fontNode->fn_Style = fontStyle;
- fontNode->fn_FontSize = textAttr->ta_YSize;
- if (dpiData != 0)
- fontNode->fn_XDPI = dpiRatio * defaultDPI;
- else
- fontNode->fn_XDPI = defaultDPI;
- PSTrace("X DPI for this font is %f\n", fontNode->fn_XDPI);
-
- fontNode->fn_TextFont = MakeATEFont(fontNode, textAttr);
- if (fontNode->fn_TextFont != 0)
- {
- AddFont(fontNode->fn_TextFont);
- diskfontMsg->df_TextFont = fontNode->fn_TextFont;
- diskfontMsg->df_ATEFont = TRUE;
- ObtainSemaphore(ateSemaphore);
- AddHead(fontList, (struct Node *)fontNode);
- ReleaseSemaphore(ateSemaphore);
- addATEFontOK = TRUE;
- if (dpiData != 0)
- ExtendFont(fontNode->fn_TextFont, dpiTag);
- else
- ExtendFont(fontNode->fn_TextFont, 0);
- fontNode->fn_BlackList = FALSE;
- /* Stupid kludge inserted to draw the Space character first, to work
- around a weird bug I have drawing the first char in a set. */
- fontNode->fn_BuiltChars[32] = CHAR_NEEDED;
- // MakeATEChars(fontNode);
- /* end of stupid kludge */
- }
- else
- {
- diskfontMsg->df_ATEFont = FALSE;
- addATEFontOK = FALSE;
- fontNode->fn_BlackList = TRUE;
- ObtainSemaphore(ateSemaphore);
- AddHead(fontList, (struct Node *)fontNode);
- ReleaseSemaphore(ateSemaphore);
- }
- }
- else
- {
- diskfontMsg->df_ATEFont = FALSE;
- addATEFontOK = FALSE;
- }
- return(addATEFontOK);
- }
-
- /* This function mimics AddATEFont except it adds fonts upon SetSoftStyle()
- calls instead of OpenDiskFont() calls. This fcn takes special
- consideration of ta_Style flags. */
- BOOL AddATEStyle(struct List *fontList, struct SSStyleMsg *sssMsg)
- {
- struct FontNode *fontNode;
- struct RastPort *sssRastPort = sssMsg->ss_RastPort;
- struct TextFont *sssTextFont = sssMsg->ss_RastPort->Font;
- static struct TextAttr dummyAttr; /* For calling MakeATEFont */
- struct SignalSemaphore *ateSemaphore = &ateFontList->ateSemaphore;
- char *currentFontName, fontName[64], dummyString[80], *dotPtr;
- char typefaceName[64], regularName[64], optFontEncoding;
- int fontSize, currentStyle, desiredStyle, lowChar, highChar;
- FILE *ateFile;
- int xDPI; /* Check if the normal font has a ratio */
- BOOL addATEStyleOK;
-
- currentFontName = sssRastPort->Font->tf_Message.mn_Node.ln_Name;
- fontSize = sssRastPort->Font->tf_YSize;
- desiredStyle = sssMsg->ss_NewStyle & sssMsg->ss_Enable;
- currentStyle = desiredStyle & (FSF_BOLD | FSF_ITALIC);
- /* Only pay attention to FSF_BOLD and FSF_ITALIC */
- /* Build search string and see if we don't already have this font */
- sprintf(fontName, "%50s / %5d / %2x", currentFontName, fontSize, currentStyle);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, fontName);
- ReleaseSemaphore(ateSemaphore);
- if (fontNode != 0)
- {
- sssMsg->ss_ATEFont = TRUE;
- sssMsg->ss_ChangedFont = fontNode->fn_TextFont;
- sssMsg->ss_SoftStyleNeeded = currentStyle ^ desiredStyle;
- return(TRUE);
- /* Hey, why work if you already have results? */
- }
-
- /* Do repeat search for normal style and copy XDPI */
- sprintf(fontName, "%50s / %5d / %2x", currentFontName, fontSize, FS_NORMAL);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, fontName);
- ReleaseSemaphore(ateSemaphore);
- if (fontNode != 0)
- xDPI = fontNode->fn_XDPI;
-
- /* OK currentStyle doesn't exist yet and it IS an ATE font. So make it. */
-
- /* Make sure the font in question is an ATE font. */
- strcpy(fontName, "FONTS:");
- strcat(fontName, currentFontName);
- dotPtr = strchr(fontName, '.');
- *dotPtr = '\0';
- /* OK try opening the file */
- ateFile = fopen(fontName, "r");
- if (ateFile == 0)
- {
- sssMsg->ss_ATEFont = FALSE;
- sssMsg->ss_SoftStyleNeeded = sssMsg->ss_NewStyle;
- return(TRUE);
- /* hey, not an ATE-ready typeface so exit */
- }
-
- /* Now search to see if requested typeface version exists */
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "%c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(regularName, dotPtr);
- strcpy(typefaceName, regularName);
- switch(currentStyle)
- {
- case 0x02: /* FSF_BOLD */
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- case 0x04: /* FSF_ITALIC */
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- case 0x06: /* FSF_BOLD | FSF_ITALIC */
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- default:
- break;
- }
- fclose(ateFile);
-
- /* If no real typeface exists for desired style, exit */
- if (strcmp(typefaceName, regularName) == 0)
- {
- sssMsg->ss_ATEFont = FALSE;
- sssMsg->ss_SoftStyleNeeded = sssMsg->ss_NewStyle;
- return(TRUE);
- }
-
- /* OK now make a new font node for this new style */
- fontNode = (struct FontNode *)AllocVec(sizeof(struct FontNode), MEMF_PUBLIC | MEMF_CLEAR);
- if (fontNode != 0)
- {
- sprintf(fontName, "%50s / %5d / %2x", currentFontName, fontSize, currentStyle);
- strcpy(fontNode->fn_Name, fontName);
- fontNode->fn_Node.ln_Name = fontNode->fn_Name;
- fontNode->fn_Node.ln_Type = NT_USER;
- fontNode->fn_Node.ln_Pri = 0;
- strcpy(fontNode->fn_TypefaceName, typefaceName);
- dotPtr = strchr(fontNode->fn_TypefaceName, '\n');
- if (dotPtr != 0)
- *dotPtr = 0;
- fontNode->fn_LowChar = lowChar;
- fontNode->fn_HighChar = highChar;
- fontNode->fn_OptFontEncoding = optFontEncoding;
- fontNode->fn_Style = currentStyle;
- fontNode->fn_FontSize = fontSize;
- fontNode->fn_XDPI = xDPI;
- dummyAttr.ta_Name = currentFontName;
- dummyAttr.ta_YSize = fontSize;
- dummyAttr.ta_Style = currentStyle;
- dummyAttr.ta_Flags = 0;
- /* Call MakeATEFont() to build this new font */
- fontNode->fn_TextFont = MakeATEFont(fontNode, &dummyAttr);
- if (fontNode->fn_TextFont != 0)
- {
- AddFont(fontNode->fn_TextFont);
- sssMsg->ss_ChangedFont = fontNode->fn_TextFont;
- sssMsg->ss_ATEFont = TRUE;
- ObtainSemaphore(ateSemaphore);
- AddHead(fontList, (struct Node *)fontNode);
- ReleaseSemaphore(ateSemaphore);
- ExtendFont(fontNode->fn_TextFont, 0);
- sssMsg->ss_SoftStyleNeeded = currentStyle ^ desiredStyle;
- addATEStyleOK = TRUE;
- fontNode->fn_BlackList = FALSE;
- /* Stupid kludge inserted to draw the Space character first, to work
- around a weird bug I have drawing the first char in a set. */
- fontNode->fn_BuiltChars[32] = CHAR_NEEDED;
- // MakeATEChars(fontNode);
- /* end of stupid kludge */
- }
- else
- {
- sssMsg->ss_ATEFont = FALSE;
- addATEStyleOK = FALSE;
- sssMsg->ss_SoftStyleNeeded = sssMsg->ss_NewStyle;
- fontNode->fn_BlackList = TRUE;
- }
- }
- else
- {
- sssMsg->ss_ATEFont = FALSE;
- sssMsg->ss_SoftStyleNeeded = sssMsg->ss_NewStyle;
- addATEStyleOK = FALSE;
- }
- return(addATEStyleOK);
- }
-
- /* Yet another mimic-er of AddATEFont, except this one builds SegLists and
- clears the fontnode after use. Used for the NewScaledDiskFont() patch */
- struct DiskFontHeader *BuildScaledDiskFont(struct TextFont *textFont, struct TextAttr *textAttr)
- {
- struct TTextAttr *taggedTextAttr;
- struct FontNode *fontNode;
- struct DiskFontHeader *dfHeader;
- UBYTE fontStyle;
- char fontName[64], regularName[64], typefaceName[64];
- char dummyString[80], *dotPtr, optFontEncoding;
- FILE *ateFile;
- int lowChar, highChar, index;
- BOOL addATEFontOK = FALSE;
- float xDPI, yDPI;
- float dpiRatio;
- struct TagItem *dpiTag;
- ULONG dpiData;
-
- if (textAttr->ta_Style & FSF_TAGGED)
- taggedTextAttr = (struct TTextAttr *)textAttr;
- else
- taggedTextAttr = 0;
-
- /* Make sure the font in question is an ATE font. */
- strcpy(fontName, "FONTS:");
- strcat(fontName, textFont->tf_Message.mn_Node.ln_Name);
- dotPtr = strchr(fontName, '.');
- *dotPtr = '\0';
- /* OK try opening the file */
- ateFile = fopen(fontName, "r");
- if (ateFile == 0)
- return(0);
-
- fontStyle = (textAttr->ta_Style) & (FSF_BOLD | FSF_ITALIC);
-
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "%c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(regularName, dotPtr);
- strcpy(typefaceName, regularName);
- switch(fontStyle)
- {
- case 0x02:
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- case 0x04:
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- case 0x06:
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- fgets(dummyString, 79, ateFile);
- sscanf(dummyString, "&c %d %d", &optFontEncoding, &lowChar, &highChar);
- dotPtr = strchr(dummyString, '.');
- dotPtr++;
- strcpy(typefaceName, dotPtr);
- break;
- default:
- break;
- }
-
- fclose(ateFile);
- /* If no real typeface exists for desired style, use plain style */
- if (strcmp(typefaceName, regularName) == 0)
- fontStyle = FS_NORMAL;
-
- dpiData = 0;
- if (taggedTextAttr != 0)
- {
- dpiTag = taggedTextAttr->tta_Tags;
- dpiData = GetTagData(TA_DeviceDPI, 0L, dpiTag);
-
- if (dpiData != 0)
- {
- xDPI = (dpiData & 0xFFFF0000) >> 16;
- yDPI = dpiData & 0x0000FFFF;
- dpiRatio = xDPI / yDPI;
- PSTrace("Typeface DPI: %d x, %d y\n", xDPI, yDPI);
- PSTrace("DPI ratio: %f\n", dpiRatio);
- }
-
- }
-
- fontNode = (struct FontNode *)AllocVec(sizeof(struct FontNode), MEMF_PUBLIC | MEMF_CLEAR);
- if (fontNode != 0)
- {
- strcpy(fontNode->fn_Name, fontName);
- fontNode->fn_Node.ln_Name = fontNode->fn_Name;
- fontNode->fn_Node.ln_Type = NT_USER;
- fontNode->fn_Node.ln_Pri = 0;
- strcpy(fontNode->fn_TypefaceName, typefaceName);
- dotPtr = strchr(fontNode->fn_TypefaceName, '\n');
- if (dotPtr != 0)
- *dotPtr = 0;
- fontNode->fn_LowChar = lowChar;
- fontNode->fn_HighChar = highChar;
- fontNode->fn_OptFontEncoding = optFontEncoding;
- fontNode->fn_Style = fontStyle;
- fontNode->fn_FontSize = textAttr->ta_YSize;
- if (dpiData != 0)
- fontNode->fn_XDPI = dpiRatio * defaultDPI;
- else
- fontNode->fn_XDPI = defaultDPI;
- PSTrace("X DPI for this font is %f\n", fontNode->fn_XDPI);
-
- fontNode->fn_TextFont = MakeATEFont(fontNode, textAttr);
- if (fontNode->fn_TextFont != 0)
- {
- if (dpiData != 0)
- ExtendFont(fontNode->fn_TextFont, dpiTag);
- // else
- // ExtendFont(fontNode->fn_TextFont, 0);
- /* Build all characters */
- for (index = lowChar; index <= highChar; index++)
- fontNode->fn_BuiltChars[index] = CHAR_NEEDED;
- addATEFontOK = MakeATEChars(fontNode);
- }
- else
- {
- addATEFontOK = FALSE;
- fontNode->fn_BlackList = TRUE;
- }
- }
- else
- {
- addATEFontOK = FALSE;
- return(0);
- }
-
- if (addATEFontOK == FALSE)
- {
- PSTrace("%%Error building scaled diskfont\n");
- FreeMem(fontNode->fn_ExtDFHeader, fontNode->fn_ExtDFHeader->edf_Length);
- FreeVec(fontNode);
- return(0);
- }
- dfHeader = &fontNode->fn_ExtDFHeader->edf_DFHeader;
- FreeVec(fontNode);
- return(dfHeader);
-
- }
-
- /* Here we build a new TextFont */
- struct TextFont *MakeATEFont(struct FontNode *fontNode, struct TextAttr *textAttr)
- {
- struct TextFont *newFont;
- struct ExtDFHeader *extDFHeader;
- FILE *afmFile;
- char lineIn[256], afmFilename[64], checkString[64], charName[24];
- int zZ, z1, z2, index, y1, y2;
- int asciiCode, llX, llY, urX, urY, xWidth;
- //structPSdevice *localPage = &fontNode->fn_Page;
-
- if (fontNode->fn_BlackList == TRUE)
- return(0);
- /* Pre-check: Make sure the typeface is in PSFonts: */
- strcpy(afmFilename, "PSFonts:");
- strcat(afmFilename, fontNode->fn_TypefaceName);
- afmFile = fopen(afmFilename, "r");
- if (afmFile == 0)
- {
- fprintf(ateOutput, "Cannot locate typeface file %s. Check your _AFM_ files or\n"
- "Re-install the typeface.\n", fontNode->fn_TypefaceName);
- fflush(ateOutput);
- fclose(afmFile);
- return(0);
- }
-
- /* Find AFM and encoding files and get charWidth & bounding box info */
- strcpy(afmFilename, "PSFonts:afms/");
- strcat(afmFilename, fontNode->fn_TypefaceName);
- strcat(afmFilename, ".afm");
- PSTrace("%%Will attempt to open %s\n", afmFilename);
- afmFile = fopen(afmFilename, "r");
- if (afmFile == 0)
- {
- PSTrace("%%Can't open AFM file\n");
- fprintf(ateOutput, "Cannot locate AFM file for typeface %s. Check your\n"
- "PSFonts/afms diectory and _ATE_ files or re-install.\n",
- fontNode->fn_TypefaceName);
- fflush(ateOutput);
- fclose(afmFile);
- return(0);
- }
-
- /* NOTICE: This routine looks for specific keywords and I'm not responsible
- if you don't use AFMs that follow Adobe FontMetrics2.0. Also notice:
- I do not check the typeface names in the .afm itself. The Install prg
- will do that stupid checking when I finish it. */
-
- fontNode->fn_OptBaseLine = 0;
- /* Search for FontBBox keyword */
- while (!feof(afmFile))
- {
- fgets(lineIn, 256, afmFile);
- sscanf(lineIn, "%s ", checkString);
- if (strcmp(checkString, "FontBBox") == 0)
- {
- llY = 0;
- sscanf(lineIn, "%s %d %d %d %d", checkString, &llX, &llY, &urX, &urY);
- PSTrace("%%Bounding box: %d %d %d %d\n", llX, llY, urX, urY);
- if (llY < 0)
- fontNode->fn_OptBaseLine = -llY;
- if (llY > 0)
- fontNode->fn_OptBaseLine = llY;
- PSTrace("%%Baseline read from AFM file at %d\n", fontNode->fn_OptBaseLine);
- break;
- }
- }
-
- /* Search for StartCharMetrics keyword */
- while (!feof(afmFile))
- {
- fgets(lineIn, 256, afmFile);
- sscanf(lineIn, "%s ", checkString);
- if (strcmp(checkString, "StartCharMetrics") == 0)
- break;
- }
- if (feof(afmFile))
- {
- fprintf(ateOutput, "Error parsing AFM file for %s. Ensure the AFM follows\n"
- "AdobeFontMetrics 2.0 spec, including bounding boxes for\n"
- "each character.\n", fontNode->fn_TypefaceName);
- fflush(ateOutput);
- fclose(afmFile);
- return(0);
- }
-
- /* OK very next statements until EndCharMetrics are width and bounding box
- info. Read it all in, compare charnames with encodingExternal and build
- width and bbox info. */
-
- while (!feof(afmFile))
- {
- asciiCode = 0;
- fgets(lineIn, 256, afmFile);
- sscanf(lineIn, "%s", checkString);
- if (strcmp(checkString, "EndCharMetrics") == 0)
- break;
- sscanf(lineIn, "C %d ; WX %d ; N %s ; B %d %d %d %d",
- &asciiCode, &xWidth, charName, &llX, &llY, &urX, &urY);
-
- if (asciiCode == -1)
- {
- for (index = fontNode->fn_LowChar; index <= fontNode->fn_HighChar; index++)
- {
- if (strcmp(encodingExternal[index], charName) == 0)
- {
- if (urX - llX < xWidth)
- urX = xWidth;
- fontNode->fn_CharWidths[index] = xWidth;
- fontNode->fn_LowLeftX[index] = llX;
- fontNode->fn_LowLeftY[index] = llY;
- fontNode->fn_UpRightX[index] = urX;
- fontNode->fn_UpRightY[index] = urY;
- break;
- }
- }
- }
- else
- {
- if ((urX - llX) < xWidth)
- urX = xWidth;
- fontNode->fn_CharWidths[asciiCode] = xWidth;
- fontNode->fn_LowLeftX[asciiCode] = llX;
- fontNode->fn_LowLeftY[asciiCode] = llY;
- fontNode->fn_UpRightX[asciiCode] = urX;
- fontNode->fn_UpRightY[asciiCode] = urY;
- }
- }
-
- if (feof(afmFile))
- {
- PSTrace("%%Disk error or format error reading AFM file\n");
- fclose(afmFile);
- return(0);
- }
-
- /* Since AddATEFont() did all the checking for this fcn, just start rendering */
- PSTrace("%%Loading typeface %s\n", fontNode->fn_TypefaceName);
- /* A bit of weeding out; these weren't needed */
- // PSIntf("/fontname /%.100s def\n", fontNode->fn_TypefaceName);
- // PSIntf("fontname findfont pop\n");
- // PSIntf("/font fontname .findfont def\n");
-
- PSIntf("/font /%.100s findfont def\n", fontNode->fn_TypefaceName);
-
- if (psError != 0)
- PSTrace("%%Error loading typeface\n");
- PSTrace("%%Encoding font\n");
- PSIntf("/newfont font maxlength dict def\n");
- PSIntf( "font\n"
- "{ exch dup /FID ne"
- "{ exch newfont 3 1 roll put } { pop pop } ifelse }\n"
- "forall\n");
- if (fontNode->fn_OptFontEncoding == 'S')
- PSIntf("newfont /Encoding encoding put\n");
- PSIntf("/_%.100s newfont definefont pop\n", fontNode->fn_TypefaceName);
- if (psError != 0)
- {
- PSTrace("%%PostScript error encoding typeface\n");
- return(0);
- }
-
- if (fontNode->fn_OptBaseLine == 0)
- {
- /* Start generating baseline info from BBox info */
- zZ = 1000 * 72 / defaultDPI; /* Formerly zZ = (1000 * 72) / optYDen */
- z1 = z2 = 0;
- for (index = fontNode->fn_LowChar; index <= fontNode->fn_HighChar; index++)
- {
- if (fontNode->fn_LowLeftY[index] < z1)
- z1 = fontNode->fn_LowLeftY[index];
- if (fontNode->fn_UpRightY[index] > z2)
- z2 = fontNode->fn_UpRightY[index];
- }
- if (z2 == z1)
- {
- PSTrace("%%All chars in this typeface are null!\n");
- psError = -1;
- return(0);
- }
- fontNode->fn_OptBaseLine = (1000 * (-z1) + (z2 - z1) / 2) / (z2 - z1);
- if ((z2 - z1 > zZ) && fontNode->fn_OptFontEncoding == 'S')
- {
- y1 = y2 = 0;
- for (index = 'A'; index <= 'Z'; index++)
- {
- if (fontNode->fn_LowLeftY[index] < y1)
- y1 = fontNode->fn_LowLeftY[index];
- if (fontNode->fn_UpRightY[index] > y2)
- y2 = fontNode->fn_UpRightY[index];
- }
- for (index = 'a'; index <= 'z'; index++)
- {
- if (fontNode->fn_LowLeftY[index] < y1)
- y1 = fontNode->fn_LowLeftY[index];
- if (fontNode->fn_UpRightY[index] > y2)
- y2 = fontNode->fn_UpRightY[index];
- }
- if (y2 - y1 <= zZ)
- fontNode->fn_OptBaseLine = (1000 * (-y1) + zZ / 2) / zZ;
- else
- fontNode->fn_OptBaseLine = (1000 * (-y1) + (y2 - y1) / 2) / (y2 - y1);
- }
- }
-
- PSTrace("%%Baseline set to %d/1000 of pixel height\n", fontNode->fn_OptBaseLine);
-
- /* Prepare memory space for the new font */
- PSTrace("%%Allocating space for new TextFont\n");
- fontNode->fn_BaseLength = sizeof(struct ExtDFHeader) + 8 * (fontNode->fn_HighChar - fontNode->fn_LowChar + 2);
- fontNode->fn_MaxWidth = 0;
- for (index = fontNode->fn_LowChar; index <= fontNode->fn_HighChar; index++)
- fontNode->fn_MaxWidth += (((fontNode->fn_UpRightX[index] * 1.3) -
- fontNode->fn_LowLeftX[index]) * fontNode->fn_FontSize * fontNode->fn_XDPI) / 72000 + 2;
- /* 72 = opt X den */
- fontNode->fn_MaxModulo = ((fontNode->fn_MaxWidth + 15) >> 3) & ~1;
- fontNode->fn_MaxCharLength = fontNode->fn_MaxModulo * fontNode->fn_FontSize;
- fontNode->fn_MaxFontLength = fontNode->fn_BaseLength + fontNode->fn_MaxCharLength + 2 + 76;
-
- /* This time: use AllocMem because this might be a diskfont seglist */
- extDFHeader = (struct ExtDFHeader *)AllocMem((fontNode->fn_MaxFontLength), (MEMF_PUBLIC | MEMF_CLEAR));
- if (extDFHeader == 0)
- {
- PSTrace("%%Cannot get memory for new TextFont\n");
- psError = -1;
- return(0);
- }
- fontNode->fn_ExtDFHeader = extDFHeader;
- extDFHeader->edf_Length = fontNode->fn_MaxFontLength;
- /* Fill dfHeader up */
- extDFHeader->edf_DFHeader.dfh_DF.ln_Name = extDFHeader->edf_DFHeader.dfh_Name;
- extDFHeader->edf_DFHeader.dfh_FileID = DFH_ID;
- /* seglist pointer one longword ahead of the extDFHeader */
- extDFHeader->edf_DFHeader.dfh_Segment = MKBADDR((ULONG)extDFHeader + 4);
- extDFHeader->edf_DFHeader.dfh_Revision = 1;
- /* Continue filling TextFont struct */
- newFont = &extDFHeader->edf_DFHeader.dfh_TF;
- fontNode->fn_CharLoc = (short *)&newFont[1];
- fontNode->fn_CharSpace = (short *)&fontNode->fn_CharLoc[(fontNode->fn_HighChar - fontNode->fn_LowChar + 2) * 2];
- fontNode->fn_CharKern = (short *)&fontNode->fn_CharSpace[fontNode->fn_HighChar - fontNode->fn_LowChar + 2];
- fontNode->fn_CharData = (char *)&fontNode->fn_CharKern[fontNode->fn_HighChar - fontNode->fn_LowChar + 2];
- fontNode->fn_CharFontName = (char *)extDFHeader->edf_DFHeader.dfh_Name;
- // fontNode->fn_CharFontName = (char *)&fontNode->fn_CharData[fontNode->fn_MaxCharLength];
- strcpy(fontNode->fn_CharFontName, textAttr->ta_Name);
- PSTrace("TextFont pointers: Font at %8X\n", newFont);
- PSTrace(" Loc at %8X\n", fontNode->fn_CharLoc);
- PSTrace(" Space at %8X\n", fontNode->fn_CharSpace);
- PSTrace(" Kern at %8X\n", fontNode->fn_CharKern);
- PSTrace(" Data at %8X\n", fontNode->fn_CharData);
- PSTrace(" Name at %8X\n", fontNode->fn_CharFontName);
- PSTrace(" Name is %s\n", fontNode->fn_CharFontName);
-
- /* Prepare remaining TextFont attributes */
- newFont->tf_Message.mn_Node.ln_Name = fontNode->fn_CharFontName;
- newFont->tf_Message.mn_Node.ln_Type = NT_FONT;
- newFont->tf_Message.mn_Length = fontNode->fn_MaxFontLength + 64;
- newFont->tf_YSize = textAttr->ta_YSize;
- newFont->tf_Style = fontNode->fn_Style;
- newFont->tf_Flags = (FPF_DISKFONT | FPF_PROPORTIONAL | FPF_DESIGNED);
- fontNode->fn_BaseLine = (textAttr->ta_YSize * fontNode->fn_OptBaseLine + 500) / 1000;
- if (fontNode->fn_BaseLine < 0)
- fontNode->fn_BaseLine = 0;
- if (fontNode->fn_BaseLine > textAttr->ta_YSize)
- fontNode->fn_BaseLine = textAttr->ta_YSize - 1;
- newFont->tf_Baseline = textAttr->ta_YSize - fontNode->fn_BaseLine - 1;
- newFont->tf_BoldSmear = textAttr->ta_YSize / 20 + 1;
- newFont->tf_LoChar = fontNode->fn_LowChar;
- newFont->tf_HiChar = fontNode->fn_HighChar;
- newFont->tf_Modulo = fontNode->fn_MaxModulo;
- newFont->tf_CharLoc = (APTR)fontNode->fn_CharLoc;
- newFont->tf_CharSpace = (APTR)fontNode->fn_CharSpace;
- newFont->tf_CharKern = (APTR)fontNode->fn_CharKern;
- newFont->tf_CharData = (APTR)fontNode->fn_CharData;
-
- /* Prepare additional values in fontNode struct */
- fontNode->fn_ActWidth = 0;
- fontNode->fn_NomWidth = 0;
- fontNode->fn_NomCount = 0;
- fontNode->fn_CharPosX = 0;
-
- /* Right here should be the end of MakeATEFont() except for tf_CharSpace */
- /* and tf_CharKern array generation. The rest will move to MakeATEChars() */
- /* And it has. This part just pre-builds the font shell */
-
- for (index = fontNode->fn_LowChar; index <= fontNode->fn_HighChar; index ++)
- {
- z1 = (fontNode->fn_LowLeftX[index] * fontNode->fn_FontSize * fontNode->fn_XDPI - 41000) / 72000;
- /* opt x den */
- z2 = (fontNode->fn_UpRightX[index] * fontNode->fn_FontSize * fontNode->fn_XDPI + 41000) / 72000;
- /* opt x den */
- if (z1 < 0)
- zZ = z2 - z1;
- else
- zZ = z2 + z1;
- fontNode->fn_CharLoc[(index - fontNode->fn_LowChar) * 2 + 1] = zZ;
- fontNode->fn_CharSpace[(index - fontNode->fn_LowChar)] = -z1 + (fontNode->fn_CharWidths[index] * fontNode->fn_FontSize * fontNode->fn_XDPI + 41000) / 72000;
- fontNode->fn_CharKern[(index - fontNode->fn_LowChar)] = z1;
- if (fontNode->fn_LowLeftY[index] != fontNode->fn_UpRightY[index])
- {
- fontNode->fn_NomWidth += (zZ * 1.3);
- fontNode->fn_NomCount++;
- }
- }
-
- /* Some extra parts of the TextFont struct missed above */
- newFont->tf_XSize = fontNode->fn_NomWidth / (fontNode->fn_HighChar - fontNode->fn_LowChar);
- /* Reset position ptr for char drawing */
- /* OK, finally the new TextFont is ready for use (maybe...) */
- if (psError != 0)
- {
- FreeMem(extDFHeader, fontNode->fn_MaxFontLength);
- return(0);
- }
-
- return(newFont);
- }
-
- /* MakeATEChars() searches fn_BuiltChars and builds characters flagged with */
- /* CHAR_NEEDED, then sets the value to CHAR_DRAWN. */
- BOOL MakeATEChars(struct FontNode *fontNode)
- {
- int index, z1, z2, zZ;
- // int y1, y2;
- struct TextFont *newFont = fontNode->fn_TextFont;
- //structPSdevice *localPage = &psParm->page;
-
- /* Check for blacklisting */
- if (fontNode->fn_BlackList == TRUE)
- return(FALSE);
-
- /* Prepare page area for the new chars */
- psParm->page.buf[0] = newFont->tf_CharData;
- psParm->page.len = fontNode->fn_MaxCharLength;
- psParm->page.depth = 1;
- psParm->page.xbytes = fontNode->fn_MaxModulo;
- psParm->page.xsize = fontNode->fn_MaxWidth;
- psParm->page.ysize = fontNode->fn_FontSize;
- psParm->page.yheight = fontNode->fn_FontSize;
-
- /* Beginning of MakeATEChars() (Fingers crossed) */
- PSsetdevice(psActivation, &psParm->page);
-
- /* OK, draw some characters. */
- /* first re-load the typeface needed... */
- // PSIntf("/fontname /%.100s def\n", fontNode->fn_TypefaceName);
- // PSIntf("fontname findfont pop\n");
- // PSIntf("/font fontname .findfont def\n");
-
- PSIntf("/font /%.100s findfont def\n", fontNode->fn_TypefaceName);
-
- PSIntf("/newfont font maxlength dict def\n");
- PSIntf( "font\n"
- "{ exch dup /FID ne"
- "{ exch newfont 3 1 roll put } { pop pop } ifelse }\n"
- "forall\n");
- if (fontNode->fn_OptFontEncoding == 'S')
- PSIntf("newfont /Encoding encoding put\n");
- PSIntf("/_%.100s newfont definefont pop\n", fontNode->fn_TypefaceName);
-
- /* ... then initmatrix the drawing area and start drawing */
- PSIntf("initmatrix\n");
- PSIntf("/xscale %d %d mul 72 div def\n", newFont->tf_YSize, fontNode->fn_XDPI);
- /* 72 = optXDen */
- PSIntf("/yscale %d %d mul 72 div def\n", newFont->tf_YSize, defaultDPI);
- /* 72 = optYDen */
- PSIntf("newfont [ xscale 0 0 yscale 0 0 ] makefont setfont\n");
-
- /* Character loop. MakeATEChars() keeps a running position ptr and fills */
- /* the CharLoc and CharKern arrays along with the CharData bitmap. */
- /* Since the Amiga uses the position ptrs in tf_CharLoc the chars can */
- /* render in any order. */
- for (index = fontNode->fn_LowChar; index <= fontNode->fn_HighChar; index ++)
- {
- if (fontNode->fn_BuiltChars[index] == CHAR_NEEDED)
- {
- z1 = (fontNode->fn_LowLeftX[index] * fontNode->fn_FontSize * fontNode->fn_XDPI - 41000) / 72000;
- /* opt x den */
- z2 = (fontNode->fn_UpRightX[index] * fontNode->fn_FontSize * fontNode->fn_XDPI + 41000) / 72000;
- /* opt x den */
- if (z1 < 0)
- zZ = z2 - z1;
- else
- zZ = z2 + z1;
- PSIntf("cstr 0 %d put\n", index);
- PSIntf("%d %d moveto ", fontNode->fn_ActWidth - z1, fontNode->fn_BaseLine);
- /* reference to optxden in y1 was here */
- PSIntf("cstr show\n");
- if (psError != 0)
- {
- PSTrace("PostScript error drawing character %d %c\n", index, index);
- break;
- }
- fontNode->fn_CharLoc[(index - fontNode->fn_LowChar) * 2] = fontNode->fn_ActWidth;
- fontNode->fn_ActWidth += (zZ * 1.3);
- fontNode->fn_BuiltChars[index] = CHAR_DRAWN;
- }
- }
- if (psError != 0)
- fontNode->fn_BlackList = TRUE;
-
- /* I really don't expect any non-PS errors here so just return(TRUE). */
- /* The font already exists and there's enough memory by this point. */
- return(TRUE);
- }
-
- /* Unloads all unused ATE fonts and fontnodes */
- void ClearUnusedATEFonts(struct FontList *fontList)
- {
- struct SignalSemaphore *listSemaphore = &ateFontList->ateSemaphore;
- struct List *localFontList = &ateFontList->fontList;
- struct FontNode *workNode, *nextNode, *tempNode;
- BOOL killFont;
- char workName[64];
-
- /* Get access to the list */
- ObtainSemaphore(listSemaphore);
-
- /* If the list is empty to begin with, exit */
- if (localFontList->lh_Head->ln_Succ == 0)
- {
- ReleaseSemaphore(listSemaphore);
- return();
- }
-
- /* Begin traversing the font list */
- workNode = (struct FontNode *)localFontList->lh_Head;
-
- for (workNode = (struct FontNode *)localFontList->lh_Head;
- workNode->fn_Node.ln_Succ; )
- {
- nextNode = (struct FontNode *)workNode->fn_Node.ln_Succ;
-
- killFont = FALSE;
-
- if (workNode->fn_BlackList == TRUE)
- killFont = TRUE;
- else if (workNode->fn_TextFont->tf_Accessors == 0)
- {
- /* if this is a styled font, make sure this isn't
- used through SetSoftStyle() */
- if (workNode->fn_Style != FS_NORMAL)
- {
- sprintf(workName, "%50s / %5d / %2x",
- workNode->fn_TextFont->tf_Message.mn_Node.ln_Name,
- workNode->fn_FontSize, FS_NORMAL);
- tempNode = (struct FontNode *)FindName(localFontList, workName);
- if (tempNode != 0)
- {
- /* So it is used via SetSoftStyle...
- check its count */
- if (tempNode->fn_TextFont->tf_Accessors == 0)
- killFont = TRUE;
- }
- else
- killFont = TRUE;
- }
- else
- killFont = TRUE;
- }
- tempNode = workNode;
- workNode = (struct FontNode *)workNode->fn_Node.ln_Succ;
-
- /* If killFont was set, remove it and the node */
- if (killFont == TRUE)
- {
- if (tempNode->fn_TextFont != 0)
- {
- RemFont(tempNode->fn_TextFont);
- StripFont(tempNode->fn_TextFont);
- FreeMem(tempNode->fn_ExtDFHeader, tempNode->fn_ExtDFHeader->edf_Length);
- // FreeVec(tempNode->fn_TextFont);
- }
- Remove((struct Node *)tempNode);
- FreeVec(tempNode);
- }
- }
- ReleaseSemaphore(listSemaphore);
-
- /* "Re-boot" the PS interpreter */
- PSdeleteact(psActivation);
-
- /* re-initalize the PostScript activation */
- PSTrace("%%Re-initalizing PostScript Activation\n");
- psParm->page.buf[0] = nameBuffer;
- psParm->page.len = 100;
- psParm->page.depth = 1;
- psParm->page.xbytes = 10;
- psParm->page.xsize = 80;
- psParm->page.ysize = 10;
- psParm->page.xden = 72;
- psParm->page.yden = 72;
- psParm->page.ydir = -1;
- psParm->memvlen = 20000;
- psParm->memflen = 10000;
- psParm->memllen = defmemllen;
- psParm->memhlen = minmemhlen;
-
- psActivation = PScreateact(psParm);
-
- /* Run ATE startup files */
- PSTrace("%%All initalization passed, re-running PS startup & encoding files\n");
- PSIntf("(%.100s) run clear\n", "PSFonts:init.ps");
- PSIntf("/encoding StandardEncoding 256 array copy def\n");
- PSIntf("[ (%.100s) run] aload length 2 idiv\n", "PSFonts:ATEencoding.ps");
- PSIntf("{ encoding 3 1 roll put } repeat\n");
- PSIntf("/cstr 1 string def\n");
-
- return;
- }
-
- /* Fcn that counts the opencount in each ATE font */
- int CountOpenFonts(void)
- {
- struct TextFont *currentFont, *nextFont;
- int openCount;
- struct TextAttr topazAttr;
-
- topazAttr.ta_Name = "topaz.font";
- topazAttr.ta_YSize = 8;
- topazAttr.ta_Style = FS_NORMAL;
- topazAttr.ta_Flags = 0;
-
- openCount = 0;
-
- /* Start by obtaining topaz.8, the first font in the system list */
- currentFont = (struct TextFont *)OpenFont(&topazAttr);
- CloseFont(currentFont);
-
- /* Now go into a Forbid() state and check the list */
- Forbid();
- nextFont = (struct TextFont *)currentFont->tf_Message.mn_Node.ln_Succ;
- while (nextFont != 0)
- {
- if (memcmp(currentFont->tf_Message.mn_Node.ln_Name, "_ATE_", 5) == 0)
- {
- openCount = openCount + currentFont->tf_Accessors;
- }
- currentFont = nextFont;
- nextFont = (struct TextFont *)currentFont->tf_Message.mn_Node.ln_Succ;
- }
- Permit();
-
- return(openCount);
- }
-
- /* Fcn which builds ATEAvailFonts struct */
- struct ATEAvailFonts *PrepATEAvailFonts(int sizeMax, int sizeInc, int diskfontSize)
- {
- struct ATEAvailFonts *tempATEAvailFonts;
- BOOL executeSuccess;
- FILE *ateListFile;
- char readLine[100], charName[32], *afATEFontNames;
- int asciiValue, afATEFonts, numAteSizes, numAteNames;
- int newSizeMax, remainderTest;
- int index;
-
- /* Check and decrease sizeMax as necessary */
- numAteSizes = sizeMax / sizeInc;
- remainderTest = numAteSizes * sizeInc;
- if (remainderTest == sizeMax)
- newSizeMax = sizeMax;
- else
- newSizeMax = remainderTest;
- if (newSizeMax <= sizeInc || sizeInc == 0)
- {
- fprintf(ateOutput, "You goofed over here\n");
- fflush(ateOutput);
- return(0);
- }
-
- /* Generate list file in T: */
- executeSuccess = Execute("List FONTS:_ATE_#? <NIL: >T:ateFonts.ate", 0, 0);
- if (executeSuccess == FALSE)
- {
- fprintf(ateOutput, "Some stupid goofup gathering ATE fonts happened.\n"
- "Make sure you have the List command in your system.\n");
- fflush(ateOutput);
- return(0);
- }
- ateListFile = fopen("T:ateFonts.ate", "r");
- if (ateListFile == 0)
- {
- fprintf(ateOutput, "This isn't supposed to happen; make sure you have T: assigned.\n");
- fflush(ateOutput);
- return(0);
- }
- fgets(readLine, 100, ateListFile); /* skip first line */
- while (!feof(ateListFile))
- {
- asciiValue = 0;
- numAteNames = 0;
- charName[0] = 0;
- readLine[0] = 0;
- fgets(readLine, 100, ateListFile);
- sscanf(readLine, "%d files - %d blocks used", &numAteNames, &asciiValue);
- if (numAteNames != 0)
- break;
- }
- if (feof(ateListFile) && numAteNames == 0)
- {
- fprintf(ateOutput, "You don't have any _ATE_ files in FONTS:.\n"
- "Run ATE Control Panel to install them.\n");
- fflush(ateOutput);
- fclose(ateListFile);
- return(0);
- }
- fclose(ateListFile);
-
- /* ATEAvailFonts struct */
- tempATEAvailFonts = (struct ATEAvailFonts *)AllocVec(sizeof(struct ATEAvailFonts)
- + numAteNames * 32,
- MEMF_PUBLIC | MEMF_CLEAR);
- if (tempATEAvailFonts == 0)
- {
- fprintf(ateOutput, "Not enough memory to get AvailFonts struct\n"
- "in place, probably not enough memory to run ATE.\n");
- fflush(ateOutput);
- return(0);
- }
-
- /* Fill out contents of ATEAvailFonts struct */
- afATEFonts = numAteNames * numAteSizes * sizeof(struct TAvailFonts);
- tempATEAvailFonts->aaf_SizeDiskFonts = diskfontSize;
- tempATEAvailFonts->aaf_SizeATEFonts = afATEFonts;
- tempATEAvailFonts->aaf_SizeATEData = numAteNames * 32 + sizeof(struct TagItem) * 2;
- tempATEAvailFonts->aaf_ATETags[0].ti_Tag = TA_DeviceDPI;
- tempATEAvailFonts->aaf_ATETags[0].ti_Data = 0x00010000 * defaultDPI + defaultDPI;
- tempATEAvailFonts->aaf_ATETags[1].ti_Tag = TAG_END;
- tempATEAvailFonts->aaf_ATETags[1].ti_Data = 0;
- /* Now build all the fontname list (Oh joy) at least it should work */
- tempATEAvailFonts->aaf_FontNames = (char *)&tempATEAvailFonts[1];/* Right after struct */
- tempATEAvailFonts->aaf_NumNames = numAteNames;
- tempATEAvailFonts->aaf_SizeATEData = sizeof(struct TagItem) * 2 + numAteNames * 32;
- afATEFontNames = tempATEAvailFonts->aaf_FontNames;
- ateListFile = fopen("T:ateFonts.ate", "r");
- /* Skip the first line */
- fgets(readLine, 100, ateListFile);
- for (index = 0; index < numAteNames; index++)
- {
- readLine[0] = 0;
- charName[0] = 0;
- fgets(readLine, 100, ateListFile);
- sscanf(readLine, "%s ", charName);
- if (charName[0] != 0)
- {
- strcpy(&afATEFontNames[index * 32], charName);
- strcat(&afATEFontNames[index * 32], ".font");
- }
- }
- fclose(ateListFile);
- tempATEAvailFonts->aaf_SizeInc = sizeInc;
- tempATEAvailFonts->aaf_SizeMax = newSizeMax;
-
- return(tempATEAvailFonts);
- }
-
- /* Nice function for PS tracing */
- void PSTrace(char *format, ...)
- {
- va_list ap;
-
- if (optTrace == TRUE)
- {
- va_start(ap, format);
- vfprintf(ateOutput, format, ap);
- fflush(ateOutput);
- va_end(ap);
- }
- return;
- }
-
- /* Nice function for PS command tracing too */
- void PSIntf(char *format, ...)
- {
- va_list ap;
- char psString[200];
-
- if (psError != 0)
- return;
-
- va_start(ap, format);
- if (optDebug == TRUE)
- {
- vfprintf(ateOutput, format, ap);
- fflush(ateOutput);
- }
- vsprintf(psString, format, ap);
- psError = PSintstring(psActivation, psString, -1, PSFLAGSTRING);
- va_end(ap);
- return;
- }
-
- __geta4 __regargs ULONG NewDFbaseExpunge(__A6 struct Library *libBase)
- {
- ULONG tempResult;
-
- tempResult = OldDFbaseExpunge(libBase);
- /* This gives a PS re-start a better chance */
-
- /* Signal the main task to unload unused stuff */
- Signal(ateMainTask, 1 << ateDfeSigBit);
-
- return(tempResult);
- }
-
- __geta4 __regargs struct TextFont *NewOpenDiskFont(__A0 struct TextAttr *textAttr, __A6 struct Library *libBase)
- {
- struct DiskfontMsg *diskFontMsg;
- struct TextFont *tempTextFont;
- struct SignalSemaphore *ateSemaphore = &ateFontList->ateSemaphore;
- struct List *fontList = &ateFontList->fontList;
- struct FontNode *fontNode;
- char *searchString;
- BOOL msgSent;
- BOOL ateFont;
-
- diskFontMsg = (struct DiskFontMsg *)AllocVec(sizeof(struct DiskfontMsg) + 64, MEMF_PUBLIC | MEMF_CLEAR);
- if (diskFontMsg != 0)
- {
- /* Search for existing font in node first */
- searchString = (char *)&diskFontMsg[1];
- sprintf(searchString, "%50s / %5d / %2x", textAttr->ta_Name, textAttr->ta_YSize, (textAttr->ta_Style & (FSF_BOLD | FSF_ITALIC)));
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, searchString);
- ReleaseSemaphore(ateSemaphore);
- if (fontNode == 0)
- {
- /* Prepare message for sending */
- diskFontMsg->df_ATEMsg.ate_MsgLength = sizeof(struct DiskfontMsg);
- diskFontMsg->df_ATEMsg.ate_DestPort = ateODFPort;
- diskFontMsg->df_TextAttr = textAttr;
- diskFontMsg->df_TextFont = 0;
- /* send message */
- msgSent = ATESendMsg((struct ATEMessage *)diskFontMsg);
- ateFont = diskFontMsg->df_ATEFont;
- tempTextFont = diskFontMsg->df_TextFont;
- }
- FreeVec(diskFontMsg);
- }
- tempTextFont = OldOpenDiskFont(textAttr, libBase);
- return(tempTextFont);
- }
-
- /* New patch for NewScaledDiskFont() */
- __geta4 __regargs struct DiskFontHeader *NewNSDF(__A0 struct TextFont *textFont, __A1 struct TextAttr *textAttr, __A6 struct Library *libBase)
- {
- char *fontName;
- struct DiskFontHeader *dfHeader;
- struct NsdfMsg *nsdfMsg;
- BOOL msgSent;
-
- fontName = textFont->tf_Message.mn_Node.ln_Name;
- if (memcmp(fontName, "_ATE_", 5) == 0)
- {
- nsdfMsg = (struct NsdfMsg *)AllocVec(sizeof(struct NsdfMsg), MEMF_PUBLIC | MEMF_CLEAR);
- if (nsdfMsg != 0)
- {
- nsdfMsg->nsdf_ATEMsg.ate_MsgLength = sizeof(struct NsdfMsg);
- nsdfMsg->nsdf_ATEMsg.ate_DestPort = ateNSDFPort;
- nsdfMsg->nsdf_TextAttr = textAttr;
- nsdfMsg->nsdf_TextFont = textFont;
- nsdfMsg->nsdf_DFHeader = 0;
- /* send message */
- msgSent = ATESendMsg((struct ATEMessage *)nsdfMsg);
- dfHeader = nsdfMsg->nsdf_DFHeader;
- }
- }
- else
- dfHeader = OldNSDF(textFont, textAttr, libBase);
-
- return(dfHeader);
-
- }
-
- __geta4 __regargs void NewText(__A1 struct RastPort *rastPort, __A0 STRPTR textString, __D0 WORD length, __A6 struct Library *libBase)
- {
- struct TextMsg *textMsg;
- struct FontNode *fontNode;
- struct SignalSemaphore *ateSemaphore = &ateFontList->ateSemaphore;
- struct List *fontList = &ateFontList->fontList;
- BOOL msgSent;
- char *searchString;
- BOOL softStyleMode = FALSE;
- BOOL localOptSoftStyles = optSoftStyles;
- UBYTE ateStyle = FS_NORMAL;
- UBYTE ssModeOldStyle = rastPort->AlgoStyle;
- struct TextFont *ssModeOldFont = rastPort->Font;
-
- textMsg = (struct TextMsg *)AllocVec(sizeof(struct TextMsg) + 64, (MEMF_PUBLIC | MEMF_CLEAR));
- if (textMsg != 0)
- {
- /* Check if SetSoftStyle was blatantly used */
- ateStyle = ssModeOldStyle & (FSF_BOLD | FSF_ITALIC);
- if (ateStyle != FS_NORMAL)
- softStyleMode = TRUE;
-
- searchString = (char *)&textMsg[1];
- /* find the fontNode */
- if (softStyleMode == TRUE)
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, ateStyle);
- else
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, rastPort->Font->tf_Style);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, searchString);
- ReleaseSemaphore(ateSemaphore);
-
- if (softStyleMode == TRUE && fontNode != 0)
- {
- if (fontNode->fn_BlackList == FALSE)
- {
- SetFont(rastPort, fontNode->fn_TextFont);
- OldSSStyle(rastPort, ssModeOldStyle ^ ateStyle,
- FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED, gfxBase);
- }
- else
- fontNode = 0;
- }
- if (fontNode == 0)
- {
- /* Repeat search for normal style */
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, FS_NORMAL);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, searchString);
- ReleaseSemaphore(ateSemaphore);
- /* If this was an ATE font without styles, cancel SoftStyle mode */
- if (fontNode != 0)
- {
- softStyleMode = FALSE;
- /* If soft styles aren't allowed on ATE fonts, change it */
- if (localOptSoftStyles == FALSE)
- rastPort->AlgoStyle = ssModeOldStyle ^ ateStyle;
- }
- }
- if (fontNode != 0)
- {
- if (fontNode->fn_BlackList == FALSE)
- {
- /* Prepare TextMsg struct for use */
- textMsg->tm_ATEMsg.ate_DestPort = ateTextPort;
- textMsg->tm_ATEMsg.ate_MsgLength = sizeof(struct TextMsg);
- textMsg->tm_RastPort = rastPort;
- textMsg->tm_FontNode = fontNode;
- textMsg->tm_Chars = textString;
- textMsg->tm_Length = length;
- /* send the message */
- msgSent = ATESendMsg((struct ATEMessage *)textMsg);
- }
- }
- FreeVec(textMsg);
- }
-
- OldText(rastPort, textString, length, libBase);
-
- if (softStyleMode == TRUE && fontNode != 0)
- {
- SetFont(rastPort, ssModeOldFont);
- OldSSStyle(rastPort, ssModeOldStyle ^ ateStyle,
- FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED, gfxBase);
- }
- if (localOptSoftStyles == FALSE && softStyleMode == FALSE && fontNode != 0)
- OldSSStyle(rastPort, ssModeOldStyle ^ ateStyle,
- FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED, gfxBase);
-
- return;
- }
-
- /* Various patches for TextLength, TextExtent, and TextFit
-
- __geta4 __regargs WORD NewTextLength(__A1 struct RastPort *rastPort, __A0 STRPTR aString, __D0 WORD strCount, __A6 struct Library *libBase)
- {
- WORD textLength;
- struct FontNode *fontNode;
- struct TextFont *oldTextFont = rastPort->Font;
- UBYTE oldStyle = rastPort->AlgoStyle;
-
- fontNode = SwapSoftStyle(rastPort);
-
- textLength = OldTextLength(rastPort, aString, strCount, libBase);
-
- if (fontNode != 0)
- UndoSwapSoftStyle(rastPort, oldTextFont, oldStyle);
-
- return(textLength);
- }
-
- __geta4 __regargs struct TextExtent *NewTextExtent(__A1 struct RastPort *rastPort, __A0 STRPTR aString, __D0 WORD strCount, __A2 struct TextExtent *tExtent)
- {
- struct TextExtent *destTextExtent;
- struct FontNode *fontNode;
- struct TextFont *oldTextFont = rastPort->Font;
- UBYTE oldStyle = rastPort->AlgoStyle;
-
- fontNode = SwapSoftStyle(rastPort);
-
- destTextExtent = OldTextExtent(rastPort, aString, strCount, tExtent, gfxBase);
-
- if (fontNode != 0)
- UndoSwapSoftStyle(rastPort, oldTextFont, oldStyle);
-
- return(destTextExtent);
- } */
-
- /* Unlike the previous patches, this patch needs a bit more intelligence.
- As such, the server will pass back a new TextFont ptr and style bits
- not yet set (such as FSF_UNDERLINED) so the patch can still set a
- software style as required. This will then SetFont() the font passed
- back and SetSoftStyle() any missing styles.
-
- Oops. Because some programs work in mysterious ways, I SetFont() the
- styled fonts in the Text() patch now, instead. */
- __geta4 __regargs ULONG NewSSStyle(__A1 struct RastPort *rastPort, __D0 ULONG newStyle, __D1 ULONG enable, __A6 struct Library *libBase)
- {
- struct SSStyleMsg *sssMsg;
- struct FontNode *fontNode;
- struct SignalSemaphore *ateSemaphore = &ateFontList->ateSemaphore;
- struct List *fontList = &ateFontList->fontList;
- ULONG stylesNeeded = newStyle;
- ULONG resultingStyle;
- ULONG ateStyle;
- BOOL msgSent;
- char *searchString;
-
- ateStyle = newStyle & enable & (FSF_BOLD | FSF_ITALIC);
- if (ateStyle != FS_NORMAL)
- {
- sssMsg = (struct SSStyleMsg *)AllocVec(sizeof(struct SSStyleMsg) + 64, (MEMF_PUBLIC | MEMF_CLEAR));
- if (sssMsg != 0)
- {
- /* Search through list for existing style first */
- searchString = (char *)&sssMsg[1];
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, ateStyle);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, searchString);
- ReleaseSemaphore(ateSemaphore);
- if (fontNode == 0)
- {
- /* Check for ATE normal style */
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, FS_NORMAL);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, searchString);
- ReleaseSemaphore(ateSemaphore);
- if (fontNode != 0)
- {
- /* prepare message struct */
- sssMsg->ss_ATEMsg.ate_DestPort = ateSSSPort;
- sssMsg->ss_ATEMsg.ate_MsgLength = sizeof(struct SSStyleMsg);
- sssMsg->ss_RastPort = rastPort;
- sssMsg->ss_FontNode = fontNode;
- sssMsg->ss_NewStyle = newStyle;
- sssMsg->ss_Enable = enable;
- sssMsg->ss_SoftStyleNeeded = newStyle;
- /* Send the message */
- msgSent = ATESendMsg((struct ATEMessage *)sssMsg);
- }
- }
- FreeVec(sssMsg);
- }
- }
-
- /* Call original function to complete any needed style change */
- resultingStyle = OldSSStyle(rastPort, newStyle, enable, libBase);
-
- return(resultingStyle);
- }
-
- /* Logic behind AvailFonts() patch:
- textAttrs use pointers to names, not the names themselves. So the names
- need to be in that memory space somewhere. I work around diskfont.library's
- AvailFonts() call by spotting the temporary AvailFontsHeader in the middle
- of the memory pool, then call it with the original parameters, and copy
- the NumEntries value. Then I add my extra data at the end of where
- diskfont.library put its extra data, and fill in the beginning of the pool
- with my (T)AvailFonts, NumEntries plus numTAs, then exit. (whew.) */
- __geta4 __regargs LONG NewAvailFonts(__A0 struct AvailFontsHeader *afhBuffer, __D0 LONG afBufSize, __D1 ULONG afFlags, __A6 struct Library *libBase)
- {
- /* Use local ptrs */
- struct ATEAvailFonts *nafAteAvailFonts;
- struct SignalSemaphore *nafSemaphore = &aafSemaphore;
- struct AvailFonts *nafAvailFonts;
- struct TAvailFonts *nafTAvailFonts;
- int diskAFSize, ateAFSize, ramAFSize, ateDataSize;
- int totalAFSize, tempAFSize;
- int numAteAfs, numEachName;
- int numAmigaAfs, index, index2;
- struct AvailFontsHeader *tempAfhBuffer;
- char *ateFontNames;
- struct TagItem *ateTags;
-
- /* First get access to the ATEAvailFonts struct */
- ObtainSemaphoreShared(nafSemaphore);
-
- /* Preload local variables */
- nafAteAvailFonts = ateAvailFonts;
- diskAFSize = nafAteAvailFonts->aaf_SizeDiskFonts;
- ateAFSize = nafAteAvailFonts->aaf_SizeATEFonts;
- ateDataSize = nafAteAvailFonts->aaf_SizeATEData;
- numEachName = nafAteAvailFonts->aaf_SizeMax / nafAteAvailFonts->aaf_SizeInc;
- numAteAfs = numEachName * nafAteAvailFonts->aaf_NumNames;
-
- /* Determine total size needed */
- ramAFSize = OldAvailFonts(afhBuffer, 0, afFlags & !(AFF_DISK), libBase);
- totalAFSize = ramAFSize;
- if (afFlags & AFF_DISK)
- totalAFSize = totalAFSize + diskAFSize + ateAFSize + ateDataSize;
- if (totalAFSize > afBufSize)
- {
- /* Reject and return space needed */
- ReleaseSemaphore(nafSemaphore);
- return(totalAFSize - afBufSize);
- }
-
- /* If they don't want diskfonts, call AvailFonts again and exit now */
- if (!(afFlags & AFF_DISK))
- {
- tempAFSize = OldAvailFonts(afhBuffer, afBufSize, afFlags, libBase);
- ReleaseSemaphore(nafSemaphore);
- return(tempAFSize);
- }
-
- /* Supposely we have enough space now. Spot the beginning of the Amiga
- font list further down the list, by NumTAs * sizeof(struct [T]TextAttr) */
- if (afFlags & AFF_TAGGED)
- ateAFSize = sizeof(struct TAvailFonts) * numAteAfs;
- else
- ateAFSize = sizeof(struct AvailFonts) * numAteAfs;
- tempAfhBuffer = (struct AvailFontsHeader *)((ULONG)afhBuffer + ateAFSize);
-
- /* Call AvailFonts() with new buffer position */
- if (diskAFSize != 0)
- tempAFSize = OldAvailFonts(tempAfhBuffer, ramAFSize + diskAFSize, afFlags, libBase);
- else
- tempAFSize = OldAvailFonts(tempAfhBuffer, ramAFSize, (afFlags & (!AFF_DISK)), libBase);
-
- /* Position other pointers past Amiga availfonts data */
- ateTags = (struct TagItem *)((ULONG)afhBuffer + ateAFSize + ramAFSize + diskAFSize);
- ateFontNames = (char *)((ULONG)afhBuffer + ateAFSize + ramAFSize + diskAFSize + sizeof(struct TagItem) * 2);
- /* Insert tagitems and font names after Amiga availfonts data */
- ateTags[0].ti_Tag = nafAteAvailFonts->aaf_ATETags[0].ti_Tag;
- ateTags[0].ti_Data = nafAteAvailFonts->aaf_ATETags[0].ti_Data;
- ateTags[1].ti_Tag = nafAteAvailFonts->aaf_ATETags[1].ti_Tag;
- ateTags[1].ti_Data = nafAteAvailFonts->aaf_ATETags[1].ti_Data;
- /* Insert font names after the tagitems */
- for (index = 0; index < nafAteAvailFonts->aaf_NumNames; index++)
- {
- strcpy(&ateFontNames[index * 32], &nafAteAvailFonts->aaf_FontNames[index * 32]);
- }
- /* Get number of Non-ATE AFs */
- numAmigaAfs = tempAfhBuffer->afh_NumEntries;
-
- /* Now insert ATE TextAttrs at the top of the list */
- afhBuffer->afh_NumEntries = numAmigaAfs + numAteAfs;
- /* Do two versions: one for AvailFonts and one for TAvailFonts */
- if (afFlags & AFF_TAGGED)
- {
- nafTAvailFonts = (struct TAvailFonts *)&afhBuffer[1];
- for (index = 0; index < nafAteAvailFonts->aaf_NumNames; index++)
- {
- for (index2 = 1; index2 <= numEachName; index2++)
- {
- nafTAvailFonts->taf_Type = AFF_DISK;
- nafTAvailFonts->taf_Attr.tta_Name = &ateFontNames[index * 32];
- nafTAvailFonts->taf_Attr.tta_YSize = nafAteAvailFonts->aaf_SizeInc * index2;
- nafTAvailFonts->taf_Attr.tta_Style = FS_NORMAL | FSF_TAGGED;
- nafTAvailFonts->taf_Attr.tta_Flags = FPF_DESIGNED | FPF_DISKFONT | FPF_PROPORTIONAL;
- nafTAvailFonts->taf_Attr.tta_Tags = ateTags;
- nafTAvailFonts++;
- }
- }
- }
- else
- {
- nafAvailFonts = (struct AvailFonts *)&afhBuffer[1];
- for (index = 0; index < nafAteAvailFonts->aaf_NumNames; index++)
- {
- for (index2 = 1; index2 <= numEachName; index2++)
- {
- nafAvailFonts->af_Type = AFF_DISK;
- nafAvailFonts->af_Attr.ta_Name = &ateFontNames[index * 32];
- nafAvailFonts->af_Attr.ta_YSize = nafAteAvailFonts->aaf_SizeInc * index2;
- nafAvailFonts->af_Attr.ta_Style = FS_NORMAL;
- nafAvailFonts->af_Attr.ta_Flags = FPF_DESIGNED | FPF_DISKFONT | FPF_PROPORTIONAL;
- nafAvailFonts++;
- }
- }
- }
-
- ReleaseSemaphore(nafSemaphore);
- return(0);
- /* whew! */
- }
-
- /* Message sender. This guy gets a lot of working out! */
- BOOL ATESendMsg(struct ATEMessage *ateMsg)
- {
- struct MsgPort *msgPort, *replyPort;
- struct Message *replyMsg;
- ULONG portSig;
-
- /* generate reply port */
- replyPort = CreateMsgPort();
- if (replyPort == 0)
- return(FALSE);
-
- /* Reply port set up. Now build the message. */
- ateMsg->ate_Message.mn_Length = ateMsg->ate_MsgLength;
- ateMsg->ate_Message.mn_ReplyPort = replyPort;
-
- /* OK we have a valid reply port and a message. Time to send it. */
- portSig = 1 << replyPort->mp_SigBit;
- msgPort = ateMsg->ate_DestPort;
- PutMsg(msgPort,(struct Message *)ateMsg);
- Wait(portSig);
- replyMsg=GetMsg(replyPort);
-
- /* So, sent the message. Now free the port & exit */
- DeleteMsgPort(replyPort);
- if ((msgPort != 0) && (replyMsg != 0))
- return(TRUE);
- else
- return(FALSE);
- }
-
- /* This function will provide a new font ptr in case the app calling
- a Text or text measuring function blatantly used a software style
- instead of asking for a style in OpenFont(). It also returns
- a fontnode for the Text() patch.
-
- struct FontNode *SwapSoftStyle(struct RastPort *rastPort, BOOL textSizer)
- {
- struct List *fontList = &ateFontList->fontList;
- struct SignalSemaphore *ateSemaphore = &ateFontList->ateSemaphore;
- struct FontNode *fontNode;
- char searchString[64];
- int checkATEvar;
- BOOL softStyleMode = FALSE;
- BOOL localOptSoftStyles = optSoftStyles;
- UBYTE ateStyle = FS_NORMAL;
- UBYTE ssModeOldStyle = rastPort->AlgoStyle;
- struct TextFont *ssModeOldFont = rastPort->Font;
-
- First check for blatant software styles
- ateStyle = ssModeOldStyle & (FSF_BOLD | FSF_ITALIC);
- checkATEvar = memcmp(rastPort->Font->tf_Message.mn_Node.ln_Name, "_ATE_", 5);
-
- if (ateStyle != FS_NORMAL && ckeckATEvar == 0)
- softStyleMode = TRUE;
- else
- return(0);
-
- if (softStyleMode == TRUE)
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, ateStyle);
- else
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, rastPort->Font->tf_Style);
-
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, searchString);
- ReleaseSemaphore(ateSemaphore);
- if (softStyleMode == TRUE && fontNode != 0)
- {
- if (fontNode->fn_BlackList == FALSE)
- {
- SetFont(rastPort, fontNode->fn_TextFont);
- OldSSStyle(rastPort, ssModeOldStyle ^ ateStyle,
- FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED, gfxBase);
- }
- else
- fontNode = 0;
- }
- if (fontNode == 0)
- {
- Repeat search for normal style
- sprintf(searchString, "%50s / %5d / %2x", rastPort->Font->tf_Message.mn_Node.ln_Name, rastPort->Font->tf_YSize, FS_NORMAL);
- ObtainSemaphoreShared(ateSemaphore);
- fontNode = (struct FontNode *)FindName(fontList, searchString);
- ReleaseSemaphore(ateSemaphore);
- If this was an ATE font without styles, cancel SoftStyle mode
-
- if (fontNode != 0)
- {
- softStyleMode = FALSE;
- If soft styles aren't allowed on ATE fonts, change it
- if (localOptSoftStyles == FALSE)
- OldSSStyle(rastPort, ssModeOldStyle ^ ateStyle,
- FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED, gfxBase);
- }
- }
-
- return(fontNode);
- }
-
- void UndoSwapSoftStyle(struct RastPort *rastPort, struct TextFont *textFont, UBYTE softStyle)
- {
-
- if (softStyle != 0)
- {
- SetFont(rastPort, textFont);
- OldSSStyle(rastPort, softStyle, FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED, gfxBase);
- }
-
- return;
- } */
-